Subscribe RSS

Posts Tagged ‘coding’

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: , , ,

Image representation (Clojure and Java) #2

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

Last time was given an image representation as a bounded function (see this post). This java class was completely written in Clojure. This representation is the equivament of an image from a mathematical view. It is not very efficient. Usually an image is stored as a 2-d array. This data structure allows short access time to the pixel values.

So, in java with ImageJ, an image is an abstract class named ImageProcessor. Four concretes implementation are proposed : ByteProcessor, ShortProcessor, FloatProcessor et ColorProcessor (see api). As previously discussed on this blog, the drawback of these kind of representation is the difficulty to handle negative negatives coordinates.

This post is thus devoted to an image representation based on an ImageProcessor, but allowing negatives coordinates. The proposed class Image is heriting from previous class Imfun.

Tags: , , , , ,

Image representation (Clojure and Java), part one

September 25th, 2009 by fmn | 3 Comments | Filed in Enseignement, Research

In a previous post (Digital images and arrays : the same thing ?) i moaned about the lack of support of negative coordinate in image representations. In order to go beyond a simple observation, and because i need it, here is my firsts lines (of code) on this subject.

First, what are the constraints? I write my programs in Clojure. Why? Because it is a Lisp and i love Lisps. Then because it is a efficient and dynamic language, running on the jvm. This last point is important because my programs need to be portable. In ordre to be really portable, my image representation needs to be usable by a java developper. Thus, I must write a class. But as i dislike Java (the language), this class will be written in Clojure. This is a good exercise of interoperability.

Definitions

From a very generalized point of view, an image is nothing else but a bounded two-dimensional function. The imfun class will be a child of clojure.lang.IFn, the interface representing functions in Clojure. This class contains an invoke method called when an instance is used as a function. It is only needed as internal state for each instance : a definition domain and a function. Here is the beginning of Imfun:

(ns tip.Imfun
  (:gen-class
   :implements [clojure.lang.IFn]
   :state state
   :init init
   :methods [[fun [] clojure.lang.IFn]
             [domain [] clojure.lang.IPersistentCollection]]
   :constructors {[clojure.lang.IPersistentCollection clojure.lang.IFn] []}))

Some details:

  • the first line gives the used namespace: Imfun,
  • :gen-class allows creation of *.class files,
  • this class implements the clojure.lang.IFn interface,
  • the internal state is store in state,
  • the initialisation of an instance is realized with the init function,
  • two methods are exposed : fun and domain,
  • the constructor arguments are : a collection (for the definition domain) and a function.

The init function must returns a vector with : 1/ the arguments to be passed to the parent constructor (nothing here), and 2/ the current instance state. the init arguments must comply the ones defined with :constructor.

(defn -init [dom f]
  [[] [dom f]])

The two methods fun and domain must returns the underlying function and the definition domain, all stored in state.

(defn -domain [this]
  (first (.state this)))
(defn -fun [this]
  (second (.state this)))

The invoke method is called when the instance is applied as a function. At this moment, the coordinates must be checked to be inside the definition domain (thanks to indom? function). If the coordinates are outside, the value 0 is returned (this will be changed in the future).

(defn indom? [dom pt]
  (let [[start end] dom
        [x y] pt]
    (and (>= x (first start))
         (<= x (first end))
         (>= y (second start))
         (<= y (second end)))))

(defn -invoke
  ([this x y] (if (indom? (.domain this) [x y])
                ((.fun this) x y)
                0))
  ([this pt] (let [[x y] pt]
               (this x y))))

Files organisation and compilation

If my working directory is work, two sub-dirs must be created: src and classes. The generated *.class files will go in classes. The arborescence in src must be conforms to the namespace. Thus the previous lines of code should be put in a file work/src/tip/Imfun.clj. The compilation is then realized with:

fredm:work> java -cp clojure.jar:./src:./classes clojure.main -e "(compile 'tip.Imfun)"

(this step can be realized in the clojure repl (read-eval-print-loop))

Use

Open a clojure repl :

fredm:work> java -cp clojure.jar:./src:./classes clojure.main -e
Clojure 1.1.0-alpha-SNAPSHOT
user=> (import '(tip Imfun))
tip.Imfun

Let’s create an image im, being defined from (-1, -1) to (1, 1) and returning the sum of the coordinates values:

fredm:work> java -cp clojure.jar:./src:./classes clojure.main -e
Clojure 1.1.0-alpha-SNAPSHOT
user=> (def f #(+ %1 %2))
#'user/f
user=> (def im (Imfun. [[-1 -1] [1 1]] f))
#'user/im

im is a bounded function, returning 0 outside of its definition domain.

user=> (.domain im)
[[-1 -1] [1 1]]
user=> (im -1 -1)
-2
user=> (im 0 1)
1
user=> (im 1 2)
0

It is even possible to apply im on two coordinates x and y, or to a collection of two elements containing the coordinates (i.e. a point):

user=> (im 1 1)
2
user=> (im [1 1])
2
user=> (im '(1 1))
2

Here it is. Next time a second class will be written, heriting Imfun in order to define images with values stores in a two-dimensional array. In fact, an ImageProcessor from ImageJ library will be used.

FMN

Tags: , , , , , ,