A 3D editing plugin
Other IJ plugins 
ImageJ plugins by Albert Cardona:
WARNING: all these plugins have been developed and tested in java 1.3.1 and after 2005 in 1.4.2, and only in MacOSX. I have no idea on how will they perform in other java distributions or operating systems. Use at your own risk.
Contents:
- Open as stack: open any set of images of any size and type (gif, jpg, tiff, png) as a stack. Adapted from the File_Opener.java plugin.
- Open multiple Biorad .pic files: open several .pic files at a time. Adapted from both File_opener.java plugin and Biorad_reader.java plugin.
- Duplicate image: duplicate an image and locate it exactly next and non-overlapping to original image. Adapted from Duplicate.java class by Wayne Rasband.
- ColorProcessor using Java Native Interface: an example on how to use the JNI with an ImageJ plugin. Read the file HowIDidColorProcessorJNI.txt for all info.
- Montage assistant plugin: construct montages easily with some sort of pseudo-drag'n'drop feature. Use control+click to display popup menu, from which rows, columns and images can be added. Open other images in ImageJ and click "refresh image list" to bring them into the popup menu. BE WARNED: all images should be of the same size; although otherwise they'll paste anyway, results will be unexpected. Works with stacks (adds each slice as a single image). Late note: refreshing list problems solved (2004-03-29). Read README file for plugin idiosyncracies on closing images and memory stuff. Even later note (2004-03-29): fixed several RGB vs GRAY8 problems.
- Open image and notes plugin: open any ImageJ supported image and an editable text file along with it. This text file will have the same name as the image plus a .txt appended. If the text file exists it will be read and displayed; else, it will be created new the first time that image is opened.
This plugin was developed after a petition from Kamran, an ImageJ user.
- Smaller: A very simple plugin to help in resizing, rotating and saving images quickly. Saves time and typing particularly when repeating the same or similar commands over an over.
Update 2005-11-16: changed behaviour so it is completely consistent. Beware the original images are closed. The name of the new file is the title of the old file plus the extension.
- QuickIJ: Updated 2004-09-16 Introducing a very simple though powerful command line emulation named IJServer that enables the browsing and launching of image files. Advantatges? One JVM running only, low memory consuming, very fast image opening after the first one. Screenshot and Thumbnail available too. // A set of small terminal based programs that use ImageJ as a library to perform simple tasks such as taking a screenshot or resizing an image. ImageJ is never launched and the processes can run on the background, which is very convenient. Mostly oriented to Unix/Linux systems, but can run on Windows too (not set up though).
- CLI: Command Line Interface plugin for the ImageJ macro interpreter. Just type in any macro code and execute by pressing intro. Select macro code from the screen and execute, copy or save it through a popup menu. Type up and down to bring back already entered commands, and TAB key expands both macro commands and image paths. Record, view, execute, edit and save macros. Use Unix-like commands (pwd, cd, ls, lsi, lsd, mv, rm) and navigate, open, and manage your files and particularly image files. Type doc to get the ImageJ macro manual (needs internet connection). There are several other add-ons; type help for all info. Simply drop the CLI_.jar file into the ImageJ plugins folder. Requires ImageJ 1.33f or higher. Despite the unix flavour, it works on Windows! Beautiful! Get the source here. Please report any bugs to the email on the left.
Updated 2005-02-02
Versions info here
What can you type at the CLI plugin? Just a few examples:
Image paths examples for Windows:
- open c:/Folder/Images/baboon.jpg
- open("baboon.jpg") (on folder c:/Folder/Images )
- open baboon*
- open *boon.jpg
- open *boon*
Doing commands:
- doCommand("Invert");
- makeRectangle(10,10,100,200);
Doing commands with magic on (just type in: magic )
- dc invert
- makeRectangle 10,10,100,200
Another example:
| User types: | Screen prints: |
| magic | --> magic is ON |
| open baboon.jpg \ | > open("/Applications/ImageJ/baboon.jpg");\ |
| makeRectangle 10,10,50,100 \ | > makeRectangle(10,10,50,100);\ |
| setColor 0,0,255 \ | > setColor(0,0,255);\ |
| fill() | > fill() |
If the ending backslashes are removed, the code is executed step by step as it is typed in.
If before starting to type the macro the user typed 'record mymacro', all the typed lines are saved into macro mymacro. At any point 'exec mymacro' can be called, even before typing 'stop' to end the recording. Typing 'view mymacro' prints the macro without executing it, and 'list' shows the names of all recorded macros. Type 'save mymacro' to open a file dialog and save it into a file.
Alternatively, select the macro text from the screen and choose the 'Execute Selection' or 'Save Selection' or 'Copy' options from the popup menu.
Recorded macros can be edited. Type 'front' to view which macro is the active one, or 'front mymacro' to start editing (recording into) 'mymacro'. The 'erase -l 10' erases line 10 from the front macro, and 'erase 4' erases the last 4 lines of the front macro.
The 'exec' function will try to execute macros from the recorded list, the current directory and the ImageJ macro directory. Thus typing 'exec Sine' will execute the SineCosineTable.txt macro, unless there is a macro whose name starts with 'Sine' in the recorded list or a text file in the current directory with such a name starting. Macros from text files executed this way will be cached into the recorded list.
If a macro .txt file contains more than one macro defined, the macro interpreter won't execute any of them. Just select the text from the screen and choose 'Execute Selection' from the popup.
- PostgreSQL save/read images as TIFF: A plugin to show how to save and read an ImagePlus as a TIFF file into a PostgreSQL database. You will need a PostgreSQL database running, a user with privileges to read and write into it, an appropriate table with at least two columns, one for the image name (String) and another for the image bytes (bytea), and also the JDBC java driver in ImageJ classpath (I'm using the driver from postgresql-8.0-311.jdbc3.jar from here). You will also need, unless you rewrite some lines, the IJError class. Developed and tested using java 1.4.2 in macosx 10.3.9.
UPDATE 20050821: fixed the image_name column, now it will work if given a different name.
- Open sequentially as stack: A plugin to open a sequence of images following the natural order, i.e. IMG_11.tif will go after IMG_6.tif. After the user selects an image file, the non-numeric characters of the name are used to filter files from that directory, thus other sequences of image files and/or other non-image files can coexist in the same directory without problems. The extension of the files to open does not have to be the same as that of the user-selected image file. Images that have different width & height than that of the first image in the sequence will not be opened.
- Jython utilities: This plugin makes it trivial to work with Jython in ImageJ. Jython is a Python implementation for Java, i.e. you can use the programming language python to script ImageJ -to make plugins without having to compile, and besides, taking advantage of the fantastically simple and intuitive (right, for some) language that python is. So, this plugin consists of a folder named "Jython" that the user places in the ImageJ/plugins directory. Then, drop any python script for ImageJ in this plugins/Jython folder and use the "Refresh Jython List" to make the new script appear, without restarting ImageJ, in the Plugins - Jython menu. Additionally, add the line:
macro "AutoRun" { run("Refresh Jython List"); }
in your macros/StartupMacros.txt file and the menu with all your jython scripts will always be present when launching ImageJ. If you already have a macro named AutoRun, then simply add the run("Refresh Jython List") inside the clauses of that macro.
The beauty of this setup is that scripts can be edited any time without ever having to compile or call the "Refresh Jython List" at all, as long as the file containing the script doesn't get its name changed. This is so because the jython engine will read them as they are, where they are.
Two sample Jython scripts are included, one to add noise to the current image, and another to show the ROI mask -if any- of the current image.
For this Jython scripts to work the jython.jar has to be included in the ImageJ java classpath. First generate the jython.jar by downloading the jython_21.class installer from SourceForge, and running "$ java jython_21.class" in a terminal. Then, for MacOSX, edit the ImageJ.app/Contents/Info.plist file to incorporate the path to the jython.jar in the classpath. See this nice tutorial on jython for ImageJ.
No more "implements PlugIn!", no more "public void run(String arghhh)!". Beware though that bugs in your jython scripts will only show when the actual line where the bug is, is executed. So a bug can live forever in a if/else branch that is "never" used, and so on (but this is of course true, although to a lesser extent, for java plugins as well). Beware!
UPDATE 20051030: following Edoardo Marcora's suggestion, jython scripts are listed with no underscores neither .py extension, so they look like regular ImageJ plugins.
UPDATE 20051103: zip file includes the Jython Interpreter and some example python scripts. Also, in this jython files the ImageJ classes do not need to be explicitly imported.
Benchmark comparison between java plugins, macros and jython scripts: I used these three files over a 600x900 pixels 8-bit image. Execution time in seconds.
All this plugin/macro/script does is to duplicate the current image, get one pixel at a time and add random noise to it.
The ImageJ builtin macro language is certainly more specific to ImageJ and thus goes through less clutter than the more generalistic jython interpreter. Still a 4x in execution time is quite astonishing. Luckily enough the biggest different is made when using the java.util.Random class instead of python'rs 'random' module.
Note that the complexity of the 3 files is quite similar, both in terms of length and in assumptions about the system. Thus the coder needs to learn several conventions before writing any of the 3 versions of this program. Stay with java plugins if speed matters to your program!
Jython though really pays off when properly optimized, and it's particularly useful to make GUIs in no time.
- Jython interpreter for ImageJ: Execute jython plugins as you type them! All ImageJ classes are pre-imported for convenience. Select text on the screen to copy, execute or save in a file.
Please note: this plugin requires java 1.4.x or above (thanks to Gary Ruben for reporting on this).
Example input:
>>> img = Windowmanager.getCurrentImage()
>>> def toStack(image):
... stack = ImageStack(image.width, image.height)
... for i in range(10):
... stack.addSlice(image.getTitle(), image.getProcessor().crop())
...
... ImagePlus("stack", stack).show()
...
>>> toStack(img)
The input above will put 10 copies of the current image or selection in the image into a stack of 10 slices. The 'toStack' function can then be called as many times as desired. The loop of course can be called directly, without setting it up in a function.
I find this setup useful for prototyping plugins. Later on the jython code can be converted to java code and run as a standard ImageJ plugin (this will be builtin in the future).
Java classes have to and can be imported any time, for example:
>>> from java.awt import FileDialog
>>> fd = FileDialog(IJ.getInstance(), "Open", FileDialog.LOAD)
>>> fd.show()
>>> file_name = fd.getFile()
>>> if None != file_name:
... Opener().openImage(fd.getDirectory, file_name).show()
...
>>>
Finally some sort of dynamic weakly-typed full-powered java for ImageJ!
Running ImageJ commands from jython:
>>> IJ.run("Select All")
None
>>> IJ.doCommand("Select All")
None
Both ways work just the same. I believe the IJ.doCommand does so in a separate thread.
Running macros from jython:
>>> IJ.runMacro("showMessage(\"called from a macro\");")
Python tricks to speed up writing:
>>> c = WindowManager.getCurrentImage
>>> img = c()
>>> print img
imp[test_8-bit.tif 600x900x1]
>>>
A script to put all TIF images from a folder in a list
>>> from java.io import File, FilenameFilter
>>> import re
>>> class Filter(FilenameFilter):
... def accept(self, dir, name):
... reg = re.compile("\.tif$")
... m = reg.search(name)
... if m:
... return 1
... else:
... return 0
...
>>>
>>> folder = "/images/art/"
>>> tifs = [Opener().openImage(folder, file.name) for file in File(folder).listFiles(Filter())]
>>> print tifs
[imp[image1.tif 600x900x1], imp[image2.tif 600x900x1], imp[image3.tif 600x900x1]]
Another example, showing operator overloading, i.e. make the '+' sign do whatever we want. In this case, it is used to add together several copies of the currently active image into a single stack:
>>> class Stack(ImageStack):
... def __init__(self, title, imp):
... ImageStack.__init__(self, imp.width, imp.height)
... self.title = title
... self.addSlice(imp.title, imp.getProcessor())
...
... def __add__(self, imp):
... if imp.width == self.width and imp.height == self.height:
... self.addSlice(imp.title, imp.getProcessor())
... else:
... print "image", imp.getTitle(), "has different dimensions. Ignoring."
... return self
...
... def show(self):
... ImagePlus(self.title, self).show()
...
>>>
>>> img = WindowManager.getCurrentImage()
>>> stack = Stack("stack", img) + img + img + img
>>> stack.show()
In the example above we could have also said:
>>> w = WindowManager
>>> stack = None
>>> for id in w.getIDList():
... img = w.getImage(id)
... if None == stack: stack = Stack("all", img)
... else: stack += img
...
>>>
>>> stack.show()
... which would have resulted in all open images being placed in a stack (well, only those of the same size as the first image in the list). Get it here. Another plugin to open all images in a sequence from a directory here.
Now one can select the text on the screen and save it in a file named "all_to_stack.py", under the plugins/Jython folder. Then, select Plugins / Jython / Refresh Jython List, and the plugin is already accessible at the Plugins / Jython menu. Unless the Jython Interpreter is open, the "print" statements should be replaced by IJ.log("text here") or the user may never see them.
Why I did this: I am not satisfied with ImageJ's macro language (too much java-like without direct access to java objects; too indirect in the way images are manipulated) and so I started to design my own. When I realised that it started to provide Lisp and Python -like features, I decided to scrap it, avoiding the creation of a new language (and lots of work), and move to improve jython's usability within ImageJ, with quite satisfying results.
Updated 2005-11-01: Fixed problem with bringing to the prompt the previously entered line. Prompt is now a JTextArea, so pasting multiple lines in it is more convenient. Since up/down arrows swap the prompt contents with previous/next entered lines, to navigate a multiline paste into the prompt the scroll and the mouse must be used.
Result of compiling a .py file into a .java and .class ImageJ plugin file: I've compiled with
$ cd /Applications/ImageJ/plugins/Jython/
$ /Applications/ImageJ/jython-2.1/jythonc -J "-classpath \
/Applications/ImageJ/ImageJ.app/Contents/Resources/Java/ij.jar" -w . Add_Noise_1.py
which resulted in the creation of Add_Noise_1.java and two class files. I deleted the .class files and adjusted the Add_Noise_1.java to implement ij.plugin.PlugIn and to have a run(String) method that calls the main(String[]) present in Add_Noise_1.java. The result: both the .py file and the .class file take about 15 seconds to run over an 600x900 pixels 8-bit image. There is no point in generating java files in this way, so I recommend direct usage of the .py files.
An example using java bean and event properties to show the current image in a new JFrame that will respond when closed:
>>> from javax.swing import JFrame
>>> from java.awt import Color, Dimension
>>> f = JFrame("Test", size=Dimension(400,400), \
... windowClosing=lambda msg: IJ.showMessage("Closing the window!"), \
... visible=1, background=Color.yellow)
...
>>>
>>> img = WindowManager.getCurrentImage()
>>> ic = img.getWindow().getCanvas()
>>> f.getContentPane().add(ic)
In pure java the above code would have taken lots of code lines. The only truly missing step is a way to check whether any image is open, but since this is a dynamic interpreter, if the 'img' var is null an error will show when trying to get the ImageCanvas 'ic', and thus it can be adjusted on the fly.
The above code could be even shorter, but then it may lose readability.
By java bean is understood the property/ies a class has such as, in JFrame, 'size', with its corresponding get and set methods. In jython any such bean can be specified within the constructor. See jython webpage on java bean properties and events.
For events, jython reads which listeners can be added to a class instance, and then which methods such listeners implement. Then any such method can be specified directly in the constructor such as the 'windowClosing' method of the WindowListener for the JFrame above, without having to generate subclasses or any redundant stuff.
Finally, methods can be referenced by name. Above I created a method on the fly, a so-called anonymous 'lambda' method (as in Lisp), but one could have defined a method such as 'closing' and assign it to the 'windowClosing':
>>> def closing(an_event):
... IJ.showMessage("Closing!")
...
>>>
>>> f = JFrame("Test", visible=1, windowClosing=closing)
Jython links:
PDF viewer: View a PDF file as a stack. This is a very simple plugin that takes advantage of the open-source jpedal library for manipulation of PDF files. You must have appropriate jar files in the ImageJ classpath, i.e. all the jars provided by the jpedal library plus the JAI jars (included in the "additional jars"). This includes: 14_os_jpedal.jar, jdom.jar, bcprov-jdk14-119.jar, jai_codec.jar, jai_core.jar, and optionally the pjes.jar (non-GPL, for fonts).
If you want to extend/customize this plugin, see the jpedal API.
PDF pages are open with a magnification of 100%. You can change this within the plugin, the "scaling" parameter.
Image Browser: Browse an endless amount of images, stacks and image sequences all together within a standard ImageJ window. The user selects a folder, and the plugin explores its files and its subfolders, recursively, and identifies single images, stacks, and image sequences. Image sequences can be composed of any type of image (grayscale, RGB, etc.) as long as the Opener class can handle them; it doesn't matter either if the dimensions of any two images in a sequence are different. So each of these 3 elements (single image, stack and image sequence) is assigned a panel that the user can:
- Click to select. The title changes to show the selected image.
- Use '<' and '>' keys to navigate the stack or sequence, or drag the scroll bar.
- Navigate with the glass (zoom) and hand tools. Also zoom with the '+' and '-' keys.
- Double-click to open in a separate window (with any tool but the glass).
- Shift double-click to release all resources, except for what shows (as awt.Image objects), so that images can be zoomed and panned using a minimal ammount of memory (with any tool but the glass).
Important: an image sequence is any set of files within the same folder that have a number immediately before the extension and share the same non-numeric part of the name. For example, img1.tif, img2.tif, img3.tif all belong to the same sequence, but img1_1.tif does not (would be shown in a different panel).
Key bindings are very limited. Besides the above, the 'w' closes the window, 'TAB' puts the window behind, and 'return' brings the ImageJ window to the front.
Under the curtains, it uses a dynamic memory cache and a fake byte processor, plus lots of other hacks I've worked through over the last few years. For example, image sequences are shown in the natural order of their numbers, and not as 1, 10, 11, .. 2, 20, 21 ...
My personal use of this plugin is for browsing instantly the 700MB CDs of image sequeces that I get from the confocal microscope facility. The whole idea was inspired in the view of the extreme crappiness and unsupported state of the LSM file format, so I default to save my confocal stacks as image sequences.
Know limitations: image sequences can only be opened as independent stacks if all its images are of the same type (8-bit, or RGB, etc). But it doesn't matter if they have different dimensions.
@@@ Feedback on bugs and problems in general would be appreciated. @@@
|