diff src/rlm/image_utils.clj @ 0:78a630e650d2

initial import
author Robert McIntyre <rlm@mit.edu>
date Tue, 18 Oct 2011 00:57:08 -0700
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/rlm/image_utils.clj	Tue Oct 18 00:57:08 2011 -0700
     1.3 @@ -0,0 +1,117 @@
     1.4 +(ns rlm.image-utils
     1.5 +  (:import [javax.swing JFrame]
     1.6 +	   [java.awt Color BorderLayout]
     1.7 +	   [ij ImagePlus IJ]
     1.8 +	   [java.lang Math]
     1.9 +	   [java.awt Graphics2D Panel]
    1.10 +	   [ij Macro]
    1.11 +	   [java.io BufferedReader InputStreamReader]
    1.12 +	   [java.awt.image BufferedImage])
    1.13 +  (:use [clojure.contrib
    1.14 +	 [math]
    1.15 +	 [def]]))
    1.16 +
    1.17 +
    1.18 +(defmulti frame-hash-multi  class)
    1.19 +
    1.20 +(defmethod frame-hash-multi ImagePlus
    1.21 +  [image+]
    1.22 +    (with-meta
    1.23 +      (let [buf (.. image+ getBufferedImage)
    1.24 +	    color (.getColorModel buf)]
    1.25 +	(apply hash-map 
    1.26 +	       (interleave 
    1.27 +		(doall (for [x (range (.getWidth image+)) y (range (.getHeight image+))]
    1.28 +			 (vector x y)))
    1.29 +		(doall (for [x (range (.getWidth image+)) y (range (.getHeight image+))]
    1.30 +			 (let [data (.getRGB buf x y)] 
    1.31 +			   (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16)
    1.32 +				     :g (bit-shift-right (bit-and 0x00ff00 data) 8)
    1.33 +				     :b (bit-and 0x0000ff data))))))))
    1.34 +      {:width  (.getWidth image+) :height (.getHeight image+)}))
    1.35 +
    1.36 +(defmethod frame-hash-multi String
    1.37 +  [image-name]
    1.38 +  (let [image+ (ImagePlus. image-name)]
    1.39 +    (frame-hash-multi image+)))
    1.40 +
    1.41 +(defn frame-hash
    1.42 +  "yields a convienent representation for the pixles in an image.
    1.43 +   Because of the size of the structvre generated, this must only be used
    1.44 +   in a transient way so that java can do it's garbage collection."
    1.45 +  [something]
    1.46 +  (frame-hash-multi something))
    1.47 +
    1.48 +
    1.49 +(def white {:r 255, :g 255, :b 255})
    1.50 +(def black {:r 0,   :g 0,   :b 0})
    1.51 +
    1.52 +(defn rgb-euclidian
    1.53 +  [{r1 :r g1 :g b1 :b} {r2 :r g2 :g b2 :b} ]
    1.54 +  (expt (+ (expt (- r1 r2) 2)
    1.55 +	  (expt (- g1 g2) 2)
    1.56 +	  (expt (- b1 b2) 2)) 0.5))
    1.57 +
    1.58 +(defn b&w
    1.59 +  "turn everything strictly black or white"
    1.60 +  [window]
    1.61 +  (with-meta
    1.62 +  (zipmap
    1.63 +   (keys window)
    1.64 +   (map (fn  [rgb] 
    1.65 +	  (if (> (rgb-euclidian rgb white) (rgb-euclidian rgb black))
    1.66 +	    black white))
    1.67 +	(vals window))) (meta window)))
    1.68 +
    1.69 +(defn frame-hash->bufferedImage
    1.70 +  [frame-hash]
    1.71 +    (let [data  (meta frame-hash)
    1.72 +	image (BufferedImage. (:width data) (:height data) BufferedImage/TYPE_INT_BGR)]
    1.73 +	
    1.74 +	(doall (for [element frame-hash] 
    1.75 +	  (let [coord  (key element) 
    1.76 +		rgb   (val element)
    1.77 +		packed-RGB 
    1.78 +		(+ (bit-shift-left (:r rgb) 16)
    1.79 +		   (bit-shift-left (:g rgb) 8)
    1.80 +		                   (:b rgb))]
    1.81 +	    (.setRGB image (first coord) (last coord) packed-RGB))))
    1.82 +	image))
    1.83 +  
    1.84 +(defmulti  display "Creates a JFrame and displays a buffered image"  class)
    1.85 +
    1.86 +(defn- makePanel [image]
    1.87 +  (proxy [Panel] [] (paint [g]  (.drawImage g image 0 0 nil))))
    1.88 +
    1.89 +(defmethod display 
    1.90 +  BufferedImage  [image] 
    1.91 +  (let [panel (makePanel image)
    1.92 +	frame (JFrame. "Oh Yeah!")]
    1.93 +    (.add frame panel) 
    1.94 +    (.pack frame) 
    1.95 +    (.setVisible frame true ) 
    1.96 +    (.setSize frame(.getWidth image) (.getHeight image))))
    1.97 + 
    1.98 +(defmethod display
    1.99 +  ImagePlus [image]
   1.100 +  (display (.getBufferedImage image)))
   1.101 +
   1.102 +(defmethod display
   1.103 +  clojure.lang.PersistentHashMap [frame-hash]
   1.104 +  (display (frame-hash->bufferedImage frame-hash)))
   1.105 +
   1.106 +(defmethod display
   1.107 +    clojure.lang.PersistentArrayMap [frame-hash]
   1.108 +    (display (frame-hash->bufferedImage frame-hash)))
   1.109 +
   1.110 +(defn rotate [degrees #^ImagePlus image]
   1.111 +  (.rotate (.getChannelProcessor image) degrees)
   1.112 +  image)
   1.113 +
   1.114 +
   1.115 +(defn-memo width [pic]
   1.116 +  (inc (first (last (sort (fn [[x0 y0] [x1 y1]] (> x1 x0)) (keys pic))))))
   1.117 +
   1.118 +(defn-memo height [pic]
   1.119 +    (inc (last (last (sort (fn [[x0 y0] [x1 y1]] (> y1 y0)) (keys pic))))))
   1.120 +