Subscribe RSS

Posts Tagged ‘coding’

A minimal ImageJ Plugin in Clojure: image inversion

January 15th, 2010 by fmn | 2 Comments | Filed in Enseignement, Research

I show in this post how to write an ImageJ plugin with Clojure. This example is taken from Digital Image Processing: An Algorithmic Introduction Using Java: an image inversion (page 32).

The goal is to invert all the pixels of a 8-bit grayscale image, turning an image into its negative. As a pixel value is coded with 8 bits, the higher possible value is 255. The operation is thus to transform each pixel value v into 255-v.

I first present the plugin in Java, with a description of the essentials elements of an ImageJ plugin. Then, i give several Clojure versions. The last is as fast as the Java one, but more reusable.

(more…)

Tags: , , , , , , , ,

ImageJ in a Sage notebook, an example of Python calling Java

November 10th, 2009 by fmn | 11 Comments | Filed in Enseignement, Research

Sage is a wonderful system: a big set of mathematical languages and libraries glued with Python. This is quite remarquable, but i use frequently Java for my image processing and analysis applications. In particular, the ImageJ framework allows to write plugins, making easy the application distribution. The aim is thus to easily access a Java library from a Python code. The complete method is described in this post, allowing to use ImageJ from a Sage notebook.

As Sage rely on Python, the key is to find a way to call Java code from Python. I found several solutions (excluding do-it-yourself stuff with RMI):

  • Javaclass : can’t make it work. However, seems to need work in order to pass data between Java and Python worlds.
  • JCC : a little bit clumsy, it particular it needs to add very large options when launching Python.
  • JPype : the simplest. A Python module with an easy usage.

JPype installation

It is quite regular:

unzip JPype-0.5.4.1.zip
cd JPype-0.5.4.1
sage -python setup.py build

Here a bug usually appears. JPype rely on the sets module, which is neither included in recent Python. There is not a lot of modification. You can download a modified version here. Beware, you must still follow the README to provide the path to your JDK installation. If the compilation is OK (you can send me a mail if not), the module is installed with:

sage -python setup.py install

Now we can work inside a Sage notebook (downloadable here).

JPype use

Quite simple:

  1. import the module,
  2. launch a java virtual machine,
  3. import one or more Java packages.

from jpype import *
startJVM(’/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client/libjvm.so’, ‘-Djava.class.path=/home/fredn/.libjar/ij.jar’)
ij = JPackage(’ij’)

The first parameter given to startJVM() is the path to the dynamical library of the JVM. To find it, you can do:

locate libjvm.so

The second parameter allows to extend the classpath in order to add libraries, here Image.

At this point, all the methods of Java-package ij are available, directly. We can by example load an image and display it in the notebook:

im = ij.IJ.openImage(”http://rsb.info.nih.gov/ij/images/lena.jpg”) ij.IJ.save(im, os.getcwd()+’/tmp.png’)
JPype allows to convert Java objects in Python objects (and vis versa), very easily. Thus a Python object is constructed from a Java one, all the methods available:
lena = ij.IJ.openImage(”http://rsb.info.nih.gov/ij/images/lena.jpg”).getProcessor().convertToByte(True) lena
<jpype._jclass.ij.process.ByteProcessor object at 0xb7ad52c>
<jpype._jclass.ij.process.ByteProcessor object at 0xb7ad52c>

We can now find Lena edges by calling a ByteProcessor method:

lenaedges = lena.duplicate()
lenaedges.findEdges()
lenaedges
<jpype._jclass.ij.process.ByteProcessor object at 0xb313652c>
<jpype._jclass.ij.process.ByteProcessor object at 0xb313652c>

To display side by side Lena and its edges, i need to get the pixel array of each ImageProcessor, by calling getIntArrray():

lenaedges.getIntArray()
<jpype._jarray.int[][] object at 0xb313a20c>
<jpype._jarray.int[][] object at 0xb313a20c>

This object is Python indexable, as a regular array. I can give it directly to the Python functions that display images. Here, the implicit conversion between primitive types is realized by JPype:

import pylab as pl
pl.gray()
pl.figure()
pl.subplot(1,2,1)
pl.imshow(lena.getIntArray())
pl.subplot(1,2,2)
pl.imshow(lenaedges.getIntArray())
pl.savefig(’tmp.png’)

(more…)

Tags: , , , , , , ,

Clojure functions with meta-data. Image representation #3

October 20th, 2009 by fmn | No Comments | Filed in Enseignement, Research

Previously on Pixel Shaker : an image is a bounded function that can be coded as a Java-class. This Java-class involves a lots codelines, even in Clojure. Today is an exploration of this concept in a more idiomatic way.

A bounded function is a function with an additional information : its definition domain. Clojure provides an handy way to deals with extra data : the metadata. The metadata is a map of data that can be added using the with-meta function. Let’s try to add a definition domain as a metadata :

user> (defn indom? [dom pt]
        (let [[start end] dom
              [x y] pt]
          (and (>= x (first start))
               (<= x (first end))
               (>= y (second start))
               (<= y (second end)))))
#'user/indom?
user> (defn f [x y] (+ x y))
#'user/f
user> (def dom [[0 0] [4 4]])
#'user/dom
user> (def bf (with-meta f {:domain dom}))
java.lang.UnsupportedOperationException (NO_SOURCE_FILE:10)

(more…)

Tags: , , ,