changeset 1:6d9bdaf919f7

added clojureDemo source
author Robert McIntyre <rlm@mit.edu>
date Fri, 20 Aug 2010 00:32:44 -0400
parents 163bf9b2fd13
children 5ed873917c34
files src/clojureDemo/ArchLearning.clj src/clojureDemo/BasicVision.clj src/clojureDemo/Defines.clj src/clojureDemo/FaceDetect.clj src/clojureDemo/GenesisPlay.clj src/clojureDemo/ImageJ.clj src/clojureDemo/LocalGenesis.class src/clojureDemo/MegaDeath.clj src/clojureDemo/OpenCv.clj src/clojureDemo/Polar_Transformer.class src/clojureDemo/ScracthPad.class src/clojureDemo/TestNetwork.class src/clojureDemo/VideoParse.clj src/clojureDemo/VideoTransforms.clj src/clojureDemo/VisionCore.clj src/clojureDemo/VisionReader.clj src/clojureDemo/WiredDemo.clj src/clojureDemo/Xuggle.clj src/clojureDemo/appeture.clj src/clojureDemo/explore.clj src/clojureDemo/import_java_fns.clj src/clojureDemo/librlm.clj src/clojureDemo/librlm.clj~ src/clojureDemo/project-euler.clj~ src/clojureDemo/project_euler.clj src/clojureDemo/project_euler.clj~ src/clojureDemo/rlm.clj~ src/clojureDemo/sys-utils.clj~ src/clojureDemo/sys_utils.clj src/clojureDemo/sys_utils.clj~ src/laser/.#rasterize.clj src/laser/rasterize.clj
diffstat 32 files changed, 4125 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/clojureDemo/ArchLearning.clj	Fri Aug 20 00:32:44 2010 -0400
     1.3 @@ -0,0 +1,562 @@
     1.4 +(ns clojureDemo.ArchLearning
     1.5 +  (:gen-class
     1.6 +   :implements [connections.WiredBox]
     1.7 +   :methods [ [process [Object] void] [setFile [Object] void] ]
     1.8 +   :post-init register))
     1.9 +
    1.10 +(use 'clojure.contrib.import-static)
    1.11 +(import '(java.io File))
    1.12 +(import '(org.apache.commons.io FileUtils))
    1.13 +(import '(javax.imageio ImageIO) )
    1.14 +(import '(javax.swing JFrame))
    1.15 +(import '(java.awt Color BorderLayout))
    1.16 +(import '(ij.plugin PlugIn))
    1.17 +(import '(ij ImagePlus IJ))
    1.18 +(import '(java.lang Math))
    1.19 +(import '(java.awt Polygon))
    1.20 +(import '(java.awt.geom Line2D$Double))
    1.21 +
    1.22 +(use 'clojureDemo.appeture)
    1.23 +
    1.24 +(import-static java.lang.Math pow abs)
    1.25 +
    1.26 +(import '(ij Macro))
    1.27 +
    1.28 +(import '(java.io BufferedReader InputStreamReader))
    1.29 +(import '(java.awt.image BufferedImage))
    1.30 +(import '(genesis Genesis))
    1.31 +(import '(utils Mark))
    1.32 +(import '(capenLow StoryProcessor))
    1.33 +(import '(connections Connections WiredBox))
    1.34 +(import '(specialBoxes BasicBox MultiFunctionBox))
    1.35 +(import '(engineering NewHardWiredTranslator))
    1.36 +
    1.37 +(import '(java.awt Polygon))
    1.38 +(import '(java.awt.geom Line2D$Double))
    1.39 +(use 'clojure.contrib.str-utils)
    1.40 +
    1.41 +
    1.42 +;genesis imports
    1.43 +(import '(http Start))
    1.44 +
    1.45 +
    1.46 +(use '[clojureDemo.Xuggle :only (video-seq trans-save flash display video-data)])
    1.47 +(use 'clojureDemo.MegaDeath)
    1.48 +
    1.49 +
    1.50 +(use 'clojure.contrib.combinatorics)
    1.51 +
    1.52 +(use 'clojure.contrib.repl-utils)
    1.53 +
    1.54 +(use 'clojureDemo.GenesisPlay)
    1.55 +
    1.56 +(use ['clojureDemo.Defines 
    1.57 +      :only '(
    1.58 +	     lian look getto human0 blow base app0 app1 app2 app3 app4 app5 
    1.59 +		  bounce0 bounce1 bounce2 bounce3 bounce4 bounce5 bounce6
    1.60 +		  collide0 collide1 collide2 collide3 collide4  
    1.61 +		  give0 give1 give2 give3 give4 target default)])
    1.62 +
    1.63 +(defn -register
    1.64 +   "equivalent to Connections.getPorts(this).addSignalProcessor(\"process\"); in Java"
    1.65 +   [this]
    1.66 +   (println "ClojureBox (register) : Register is run 
    1.67 +    only when the object is created, as if it were a constructor.")
    1.68 +   (. (connections.Connections/getPorts this) addSignalProcessor "process"))
    1.69 +
    1.70 +(defn -process [ this obj ]
    1.71 +  (println "ClojureBox (process) :  This is a LISP function, 
    1.72 +   being called through Java, through the wiredBox metaphor.")
    1.73 +  (.transmit (Connections/getPorts this)  obj))
    1.74 +
    1.75 +(defn -getName
    1.76 +  "the [_] means that  the function gets an explicit 'this'
    1.77 +    argument, just like python. In this case we don't care about it."
    1.78 +  [_]  "ArchLearning")
    1.79 +
    1.80 +
    1.81 +
    1.82 +
    1.83 +
    1.84 +(def output-base (File. "/home/r/Desktop/output-vision"))
    1.85 +(def rsgs (with-meta (take 10 gs) (meta gs)))
    1.86 +(def rrsgs (with-meta (take 3 rsgs) (meta gs)))
    1.87 +; a concept is going to be derived from Genesis' own xml based representations.
    1.88 +; this is an form of archlearning which figures out a function that representes
    1.89 +; the concepts.
    1.90 +
    1.91 +
    1.92 +(def black {:r 0  :g 0 :b 0})
    1.93 +(def white {:r 255 :g 255 :b 255})
    1.94 +
    1.95 +
    1.96 +(defn window-frame
    1.97 +  "analyzes a frame in terms of lots of tiny windows which 
    1.98 +   each try to find some sort of edge. keeps coordinates."
    1.99 +  ([x-form frame]
   1.100 +     (let [lines (frame-windows x-form frame)]
   1.101 +       (zipmap (for [x lines] (first (rest x)))
   1.102 +	       lines)))
   1.103 +  ([frame]
   1.104 +     (window-frame identity frame)))
   1.105 +
   1.106 +
   1.107 +(defn intense-select-x-form
   1.108 +  "discard silly gray things"
   1.109 +  [window]
   1.110 +  (with-meta
   1.111 +    (zipmap
   1.112 +     (keys window)
   1.113 +     (map (fn  [rgb]
   1.114 +	    (let [spread (- (max (:r rgb) (:g rgb) (:b rgb)) (min (:r rgb) (:g rgb) (:b rgb)))]
   1.115 +	      (if (> spread 45)
   1.116 +		rgb
   1.117 +		{:r 0 :g 0 :b 0}))) (vals window)))  (meta window)))
   1.118 +
   1.119 +(defn edges-x-form
   1.120 +  [window]
   1.121 +  (frame-hash (ImagePlus. "sad :(" (overlay-draw blank (frame-windows window)))))
   1.122 +
   1.123 +   
   1.124 +
   1.125 +(defn rgb-max
   1.126 +  [rgb1 rgb2]
   1.127 +  {:r (max (:r rgb1) (:r rgb2))
   1.128 +   :g (max (:g rgb1) (:g rgb2))
   1.129 +   :b (max (:b rgb1) (:b rgb2))})
   1.130 +
   1.131 +(defn frame-hash-add
   1.132 +  [frame1 frame2]
   1.133 +  (with-meta
   1.134 +  (let [indexes (apply hash-set (concat (keys frame1) (keys frame2)))]
   1.135 +    (zipmap indexes (for [x indexes] (rgb-max (frame1 x black)  (frame2 x black))))) (meta frame1)))
   1.136 +
   1.137 +
   1.138 +
   1.139 +(defn vid-seq-add
   1.140 +  "for black and white video-sequences. Just adds them together into one image sequence"
   1.141 +  [vid-seq1 vid-seq2]
   1.142 +  (with-meta 
   1.143 +    (map  #(ImagePlus. "ADD B&W" (frame-hash->bufferedImage %)) (map frame-hash-add (map frame-hash vid-seq1) (map frame-hash vid-seq2)))
   1.144 +    (meta vid-seq1)))
   1.145 +
   1.146 +(defn edges-center-draw
   1.147 +  ([base edges]
   1.148 +     (frame-hash-add
   1.149 +      base
   1.150 +      (zipmap (keys edges) (repeat white))))
   1.151 +  ([edges]
   1.152 +     (edges-center-draw blank edges)))
   1.153 +
   1.154 +(defn edge-dot-x-form
   1.155 +  "gives a new frame-hash with only the edge points, all white."
   1.156 +  [frame]
   1.157 +  (edges-center-draw (window-frame frame)))
   1.158 +
   1.159 +  
   1.160 +(defn rgb-euclidian
   1.161 +  [{r1 :r g1 :g b1 :b} {r2 :r g2 :g b2 :b} ]
   1.162 +  (pow (+ (pow (- r1 r2) 2)
   1.163 +	  (pow (- g1 g2) 2)
   1.164 +	  (pow (- b1 b2) 2)) 0.5))
   1.165 +  
   1.166 +(defn rgb-sub
   1.167 +  [tolerance rgb1 rgb2]
   1.168 +  (if (< (rgb-euclidian rgb1 rgb2) tolerance) black white))
   1.169 +
   1.170 +
   1.171 +
   1.172 +(defn frame-subtract
   1.173 +  [tolerance frame1 frame2]
   1.174 +  (with-meta
   1.175 +  (let [indexes (apply hash-set (concat (keys frame1) (keys frame2)))]
   1.176 +    (zipmap indexes (for [x indexes] (rgb-sub tolerance (frame1 x)  (frame2 x))))) (meta frame1)))
   1.177 +
   1.178 +
   1.179 +(defn image-subtract
   1.180 +  [tolerance [img1 img2]]
   1.181 +  (frame-subtract tolerance (frame-hash img1) (frame-hash img2)))
   1.182 +
   1.183 +
   1.184 +(defn motion-detect
   1.185 +  ([tolerance video-seq]
   1.186 +     (with-meta
   1.187 +       (map (partial image-subtract tolerance) (partition 2 1 video-seq)) (meta video-seq)))
   1.188 +  ([video-seq]
   1.189 +     (motion-detect 40 video-seq)))
   1.190 +
   1.191 +(defn motion-x-form
   1.192 +  ([tolerance video-seq]
   1.193 +     (with-meta    
   1.194 +       (map  #(ImagePlus. "motion-detect!" (frame-hash->bufferedImage %)) (motion-detect tolerance video-seq))
   1.195 +       (meta video-seq)))
   1.196 +  ([video-seq] 
   1.197 +     (motion-x-form 40 video-seq)))
   1.198 +;the edge detector is what finds objects.
   1.199 +;movement disambiguates between different ways of interperting what objects are there
   1.200 +;color / other qualifiers enable focus on a subset of objects, and can give objects names.
   1.201 +
   1.202 +
   1.203 +
   1.204 +  
   1.205 +
   1.206 +(defn find-an-object
   1.207 +  "tries to find a single object from the current sensory-buffer, which
   1.208 +   is a video-seq for now. My idea here is for this to feed-back on itself,
   1.209 +   adjusting parameters till it can find it's target, and then using those 
   1.210 +   to construct an representation of the object in terms of how to find it using
   1.211 +   other visual routines paramaters."
   1.212 +  [video-seq])
   1.213 +
   1.214 +
   1.215 +
   1.216 +(defn transform
   1.217 +  [x-form video-seq]
   1.218 +  (with-meta
   1.219 +    (map (fn [imgPlus]
   1.220 +	   (let [play (frame-hash imgPlus)]
   1.221 +	     (x-form play)))
   1.222 +	 video-seq)
   1.223 +    (meta video-seq)))
   1.224 +
   1.225 +
   1.226 +(defn apply-x-form
   1.227 +  [x-form video-seq]
   1.228 +  (with-meta
   1.229 +    (map #(ImagePlus. "transformed!" (frame-hash->bufferedImage %))
   1.230 +	 (map (fn [imgPlus]
   1.231 +		(let [play (frame-hash imgPlus)]
   1.232 +		  (x-form play)))
   1.233 +	      video-seq))
   1.234 +    (meta video-seq)))
   1.235 +
   1.236 +
   1.237 +
   1.238 +(defn only-white
   1.239 +  "reduce the image to only its white points"
   1.240 +  [window]
   1.241 +  (with-meta
   1.242 +  (let [new-keys
   1.243 +	(filter  #(= white (window %)) (keys window))]
   1.244 +    (zipmap new-keys (map window new-keys))) (meta window)))
   1.245 +
   1.246 +
   1.247 +
   1.248 +
   1.249 +(defn white-sum 
   1.250 + [& rgbs]
   1.251 + (let[ wht-map {white 1}]
   1.252 + (reduce + (map #(wht-map % 0) rgbs))))
   1.253 +
   1.254 +(defn island?
   1.255 +  "return false if there's nothing around it within a certain radius"
   1.256 +  [window [x y]]
   1.257 +  (let [radius 3]
   1.258 +    (<= (apply white-sum (vals (rectangle-window x y radius radius window))) 1)))
   1.259 +
   1.260 +(defn white-border
   1.261 +  "anything that relies on a hack like this to work is wrong"
   1.262 +  [window]
   1.263 +  (with-meta
   1.264 +    (let [info (meta window)]
   1.265 +      (into window
   1.266 +	    (zipmap
   1.267 +	     (for [x (range (:width info)) y (range (:height info)) 
   1.268 +		   :when (or (= (-(:width info) 1) x) (= (- (:height info) 1) y) (= 0 y) (= 0 x))] [x y])
   1.269 +	     (repeat white))))(meta window)))
   1.270 +
   1.271 +(defn polygonize
   1.272 +   "for each edge-point, try to connect it with all the edge points around it, 
   1.273 +   or obliterate it if it doesn't have any edge points close by."
   1.274 +  [window]
   1.275 +  (with-meta
   1.276 +  (let [edges (only-white window)]
   1.277 +    (let [new-keys
   1.278 +	  (filter (comp not (partial island? window)) (keys window))]
   1.279 +      (let [ready-points (zipmap new-keys (map window new-keys))]
   1.280 + (meta window))))))
   1.281 +
   1.282 +
   1.283 +(defn connect-the-dots
   1.284 +  [radius window]
   1.285 +  (let [edge-points (white-border (only-white window))
   1.286 +	image  (frame-hash->bufferedImage window)
   1.287 +	g2 (.getGraphics image)]
   1.288 +    (doall
   1.289 +     (for [[x y] (keys edge-points)]
   1.290 +       
   1.291 +       (let [points  (apply cartesian-product (repeat 2 (keys (only-white (rectangle-window x y radius radius edge-points)))))]
   1.292 +	(if (not (empty? points))
   1.293 +	  (doall
   1.294 +	  (for [[[x1 y1][x2 y2]] points]
   1.295 +	    (.drawLine g2 x1 y1 x2 y2)))))))
   1.296 +    (frame-hash (ImagePlus. "stupid..."  image))))
   1.297 +
   1.298 + 
   1.299 +(defn blob-x-form
   1.300 +  [window]
   1.301 +  (with-meta 
   1.302 +    ((comp (partial connect-the-dots 4) edge-dot-x-form) window)
   1.303 +  (meta window)))
   1.304 +
   1.305 +
   1.306 +
   1.307 +
   1.308 +(defn connect-points
   1.309 + [frame-hash overlay]
   1.310 + (let [image  (frame-hash->bufferedImage frame-hash)
   1.311 +       g2 (.getGraphics image)]
   1.312 +   (doall (for [ x overlay] 
   1.313 +     (let [x1 (ffirst x) y1 (second (first x)) x2 (first (last x)) y2 (last (last x))] 
   1.314 +       (.drawLine g2 x1 y1 x2 y2))))
   1.315 +     image))
   1.316 +
   1.317 +
   1.318 +(defn disambiguate-edges
   1.319 +  "Like in project Prakesh, the thing that lets you discern shapes
   1.320 +   is watching them *move* coherently. After many months of this 
   1.321 +   motion-boosting, the edge-detector itself becomes good enogh to 
   1.322 +   analyze static pictures without motion.  This function takes edges
   1.323 +   and tries to combine them into lines, dividing the world into
   1.324 +   polygonal regions.  Motion is used to associate two regions together.
   1.325 +   associated with those points, that information is also used."
   1.326 +  [edges motion]
   1.327 +)
   1.328 +  
   1.329 +
   1.330 +(defn triple-seq
   1.331 +  [triple]
   1.332 +  (list (.getFirst triple) (.getSecond triple) (.getThird triple)))
   1.333 +
   1.334 +(defn contains-word?
   1.335 +  [word triple]
   1.336 +  (contains? (set  (map (fn [s] (re-sub #"-\d+" "" s)) (triple-seq triple))) word))
   1.337 +
   1.338 +
   1.339 +(defn write 
   1.340 +  [reference]
   1.341 +  (fn [x] (dosync 
   1.342 +	   (println "wrote "  " to " "ref.")
   1.343 +	   (ref-set reference x))))
   1.344 +
   1.345 +
   1.346 +;; (defn join-point-lists
   1.347 +;;   [pointlist1 pointlist2]
   1.348 +;;   (for [x  :while (not(= x 5))] x)))
   1.349 +
   1.350 +(defn extract-single-blob
   1.351 +  "find the biggest blob in an image and return it"
   1.352 +  [window]
   1.353 +  ;we're assuming that there are only blobs left -- funning this on an unprocessed
   1.354 +  ;image will just return the entire image
   1.355 +  (map list window))
   1.356 +
   1.357 +
   1.358 +
   1.359 +
   1.360 +(def gen-out (ref nil))
   1.361 +(def triple (ref nil))
   1.362 +
   1.363 +
   1.364 +
   1.365 +(def gen1 (ref ()))
   1.366 +(def gen2 (ref ()))
   1.367 +(def gen3 (ref ()))
   1.368 +(def gen4 (ref ()))
   1.369 +(def gen5 (ref ()))
   1.370 +(def gen6 (ref ()))
   1.371 +(def gen7 (ref ()))
   1.372 +(def gen8 (ref ()))
   1.373 +
   1.374 +
   1.375 +(defn make-color-generator
   1.376 +  []
   1.377 + (let [r (java.util.Random. 58)
   1.378 +       g (java.util.Random. 125)
   1.379 +       b (java.util.Random. 8)]
   1.380 +   #(hash-map :r (.nextInt r 255)  :g (.nextInt r 255)   :b (.nextInt r 255))))
   1.381 +
   1.382 +
   1.383 +;a blob is a collection of:
   1.384 +;points, colors
   1.385 +;other blobs
   1.386 +;so, a window is a blob too.
   1.387 +
   1.388 +
   1.389 +
   1.390 +
   1.391 +
   1.392 +
   1.393 +;; (defn blob-color-absob
   1.394 +;;   [blob1 blob2]
   1.395 +;;   (if (and (< (rgb-euclidian (color-avg blob1) (color-avg blob2)) 20) (close-together blob1 blob2))
   1.396 +;;     (combine blob1 blob2)
   1.397 +;;     '(blob1 blob2)))
   1.398 +  
   1.399 +
   1.400 +(defn make-test-box
   1.401 +  "stupid."
   1.402 +  []
   1.403 +  (let [box (proxy [MultiFunctionBox] [] (getName [] "test-box [clojure]") 
   1.404 +		   (process1 [obj] ((write gen1) obj))
   1.405 +		   (process2 [obj] ((write gen2) obj))
   1.406 +		   (process3 [obj] ((write gen3) obj))
   1.407 +		   (process4 [obj] ((write gen4) obj))
   1.408 +		   (process5 [obj] ((write gen5) obj))
   1.409 +		   (process6 [obj] ((write gen6) obj))
   1.410 +		   (process7 [obj] ((write gen7) obj))
   1.411 +		   (process8 [obj] ((write gen8) obj)))]
   1.412 +    
   1.413 +    (.addSignalProcessor (Connections/getPorts box) "PORT1" "process1")
   1.414 +    (.addSignalProcessor (Connections/getPorts box) "PORT2" "process2")
   1.415 +    (.addSignalProcessor (Connections/getPorts box) "PORT3" "process3")
   1.416 +    (.addSignalProcessor (Connections/getPorts box) "PORT4" "process4")
   1.417 +    (.addSignalProcessor (Connections/getPorts box) "PORT5" "process5")
   1.418 +    (.addSignalProcessor (Connections/getPorts box) "PORT6" "process6")
   1.419 +    (.addSignalProcessor (Connections/getPorts box) "PORT7" "process7")
   1.420 +    (.addSignalProcessor (Connections/getPorts box) "PORT8" "process8")
   1.421 +    box))
   1.422 +
   1.423 +
   1.424 +
   1.425 +(defn writer-box
   1.426 +  [reference]
   1.427 +  (let [box (proxy [MultiFunctionBox] [] 
   1.428 +	      (getName [] "ref-set\n [clojure]")
   1.429 +	      (process1 [obj] ((write reference) obj)))]
   1.430 +     (.addSignalProcessor (Connections/getPorts box) "process1")
   1.431 +     box))
   1.432 +
   1.433 +
   1.434 +
   1.435 +
   1.436 +(def triples  (ref ()))
   1.437 +(def parse    (ref ()))
   1.438 +(def raw      (ref ()))
   1.439 +(def idioms   (ref ()))
   1.440 +(def yes-no   (ref ()))
   1.441 +(def imagine  (ref ()))
   1.442 +(def traj     (ref ()))
   1.443 +(def action   (ref ()))
   1.444 +(def transfer (ref ()))
   1.445 +(def pix      (ref ()))
   1.446 +(def property (ref ()))
   1.447 +
   1.448 +(use 'clojure.contrib.str-utils)
   1.449 +
   1.450 +(defn process-video-and-subtitles
   1.451 +  [this file]
   1.452 +  ;we're looking for a text file of the same name as the video file.
   1.453 +  (let [subtitles (File. (.getParent file) (str (last (first (re-seq #"(^.*)\.avi$" (.getName file)))) ".txt"))]
   1.454 +    (dorun 
   1.455 +    (for [line (re-split #"\n" (slurp (str subtitles)))]
   1.456 +      (do (println line)
   1.457 +      (.transmit (Connections/getPorts this)  line)))))
   1.458 +  (display (first (video-seq file))))
   1.459 +
   1.460 +(defn process-triple
   1.461 +  [this triple]
   1.462 +  (println "RLM [vision-box]: " triple))
   1.463 +
   1.464 +(defn visionBox
   1.465 +  []
   1.466 +  (let [box (proxy [MultiFunctionBox] [] 
   1.467 +	      (getName [] "VisionBox \n [clojure]")
   1.468 +	      (process1 [obj] (process-video-and-subtitles this obj))
   1.469 +	      (process2 [obj] (process-triple this obj)))]
   1.470 +  (.addSignalProcessor (Connections/getPorts box) "video-in" "process1")
   1.471 +  (.addSignalProcessor (Connections/getPorts box) "triple-in" "process2")
   1.472 +
   1.473 +  (println "the good box")
   1.474 +  box))
   1.475 +
   1.476 +  
   1.477 +
   1.478 +
   1.479 +
   1.480 +(defn custom-genesis
   1.481 +  "connects the writer boxes to genesis"
   1.482 +  []
   1.483 +  (Connections/obliterateNetwork)
   1.484 +  (let [stupid-box (make-test-box) genesis (Genesis.) vis-box (visionBox) ]
   1.485 +    (Connections/wire "tripple port" (.getStartParser genesis) (writer-box triples))
   1.486 +    (Connections/wire "parse" (.getStartParser genesis) (writer-box parse))
   1.487 +    (Connections/wire "result" (.getNewSemanticTranslator genesis) (writer-box raw))
   1.488 +    (Connections/wire (.getIdiomExpert genesis) (writer-box idioms))
   1.489 +    (Connections/wire "yes-no question" (.getCommandExpert genesis) (writer-box yes-no))
   1.490 +    (Connections/wire "imagine" (.getCommandExpert genesis)  (writer-box imagine))
   1.491 +    (Connections/wire "viewer" (.getTrajectoryExpert genesis) (writer-box traj))
   1.492 +    (Connections/wire "viewer" (.getActionExpert genesis) (writer-box action))
   1.493 +    (Connections/wire "next" (.getTransferExpert genesis) (writer-box transfer))
   1.494 +    (Connections/wire  (.getRachelsPictureFinder genesis) (writer-box pix))
   1.495 +    (Connections/wire "viewer" (.getPropertyExpert genesis) (writer-box property))
   1.496 +    (Connections/wire "tripple port" (.getStartParser genesis) "triple-in" vis-box)
   1.497 +    
   1.498 +
   1.499 +    (Connections/wire (.getArchLearning genesis) "video-in" vis-box)
   1.500 +    (Connections/wire  vis-box "sentence" (.getStartParser genesis))
   1.501 +    
   1.502 + genesis))
   1.503 +
   1.504 +
   1.505 +(use 'clojure.contrib.def)
   1.506 +
   1.507 +(defvar learning-hash  {}
   1.508 +  "Right now this serves as the visual memory.  
   1.509 +   It's full of verbs/objects and the programs
   1.510 +   that find them.")
   1.511 +
   1.512 +(def green {:r 0 :g 200 :b 0})
   1.513 +(def blue  {:r 0  :g 0  :b 255})
   1.514 +(def red   {:r 255 :g 0 :b 0})
   1.515 +
   1.516 +
   1.517 +(defn color-similar?
   1.518 +  [threshold window color coord]
   1.519 +  (< (rgb-euclidian (window coord) color) threshold))
   1.520 +;should also have the same "shape" here
   1.521 +
   1.522 +(defn color-select
   1.523 +     [threshold color window]
   1.524 +     (with-meta
   1.525 +       (let [new-keys
   1.526 +	     (filter  (partial color-similar? threshold window color) (keys window))]
   1.527 +	 (zipmap new-keys (map window new-keys)))
   1.528 +	   (meta window)))
   1.529 +
   1.530 +
   1.531 +
   1.532 +(defn object-sequence
   1.533 +  "get's the largest blob of the given color from a video sequence."
   1.534 +  [color video-seq]
   1.535 + (apply-x-form (comp (partial color-select 135 color) intense-select-x-form) rrsgs))
   1.536 +
   1.537 +(defn -setFile
   1.538 +  [this file]
   1.539 +  (println "file is " file)
   1.540 +  (.process this file))
   1.541 +
   1.542 +
   1.543 +
   1.544 +
   1.545 +(comment (things you can do that will actually work!)
   1.546 +
   1.547 +(do (use :reload-all 'clojureDemo.ArchLearning) (in-ns 'clojureDemo.ArchLearning))
   1.548 +
   1.549 +(display (overlay-draw (green-select-x-form play) (frame-windows green-select-x-form play )))
   1.550 +
   1.551 +;vision stuff
   1.552 +
   1.553 +(def edgesD (transform window-frame rrsgs))
   1.554 +
   1.555 +(doall 
   1.556 + (def edgesI (apply-x-form edges-x-form rrsgs))
   1.557 + (display (rectangle-window 50 50 50 50 (frame-hash (nth edgesI 1))))
   1.558 + )
   1.559 +
   1.560 +(def polyjuice (white-border (only-white (edge-dot-x-form play))))
   1.561 +
   1.562 +(count  (color-select 135 red (intense-select-x-form (frame-hash (last sg)))))
   1.563 +(trans-save (File. output-base "only-red.avi")(apply-x-form (comp (partial color-select 135 red) intense-select-x-form) rrsgs))
   1.564 +)
   1.565 +
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/clojureDemo/BasicVision.clj	Fri Aug 20 00:32:44 2010 -0400
     2.3 @@ -0,0 +1,85 @@
     2.4 +(ns clojureDemo.BasicVision)
     2.5 +
     2.6 +
     2.7 +(use 'clojure.contrib.import-static)
     2.8 +(import '(java.io File))
     2.9 +(import '(org.apache.commons.io FileUtils))
    2.10 +(import '(javax.imageio ImageIO) )
    2.11 +(import '(javax.swing JFrame))
    2.12 +(import '(java.awt Color BorderLayout))
    2.13 +(import '(ij.plugin PlugIn))
    2.14 +(import '(ij ImagePlus IJ))
    2.15 +(import '(java.lang Math))
    2.16 +(import '(java.awt Polygon))
    2.17 +(import '(java.awt.geom Line2D$Double))
    2.18 +
    2.19 +(use 'clojureDemo.appeture)
    2.20 +
    2.21 +(import-static java.lang.Math pow abs)
    2.22 +
    2.23 +(import '(ij Macro))
    2.24 +
    2.25 +(import '(java.io BufferedReader InputStreamReader))
    2.26 +(import '(java.awt.image BufferedImage))
    2.27 +(import '(genesis Genesis))
    2.28 +(import '(utils Mark))
    2.29 +(import '(capenLow StoryProcessor))
    2.30 +(import '(connections Connections WiredBox))
    2.31 +(import '(specialBoxes BasicBox MultiFunctionBox))
    2.32 +(import '(engineering NewHardWiredTranslator))
    2.33 +
    2.34 +(import '(java.awt Polygon))
    2.35 +(import '(java.awt.geom Line2D$Double))
    2.36 +(use 'clojure.contrib.str-utils)
    2.37 +
    2.38 +
    2.39 +;genesis imports
    2.40 +(import '(http Start))
    2.41 +
    2.42 +
    2.43 +(use '[clojureDemo.Xuggle :only (video-seq trans-save flash display video-data)])
    2.44 +(use 'clojureDemo.MegaDeath)
    2.45 +
    2.46 +
    2.47 +(use 'clojure.contrib.combinatorics)
    2.48 +
    2.49 +(use 'clojure.contrib.repl-utils)
    2.50 +
    2.51 +(use 'clojureDemo.GenesisPlay)
    2.52 +(use 'clojureDemo.ArchLearning)
    2.53 +
    2.54 +(use ['clojureDemo.Defines 
    2.55 +      :only '(
    2.56 +	     lian look getto human0 blow base app0 app1 app2 app3 app4 app5 
    2.57 +		  bounce0 bounce1 bounce2 bounce3 bounce4 bounce5 bounce6
    2.58 +		  collide0 collide1 collide2 collide3 collide4  
    2.59 +		  give0 give1 give2 give3 give4 target default)])
    2.60 +
    2.61 +
    2.62 +
    2.63 +; a concept is going to be derived from Genesis' own xml based representations.
    2.64 +; this is an form of archlearning which figures out a function that representes
    2.65 +; the concepts.
    2.66 +
    2.67 +
    2.68 +     
    2.69 +
    2.70 +
    2.71 +
    2.72 +
    2.73 +
    2.74 +
    2.75 +
    2.76 +
    2.77 +
    2.78 +
    2.79 +
    2.80 +
    2.81 +
    2.82 +
    2.83 +
    2.84 +
    2.85 +(comment
    2.86 +
    2.87 +(do (use :reload-all 'clojureDemo.BasicVision) (in-ns 'clojureDemo.BasicVision))
    2.88 +)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/clojureDemo/Defines.clj	Fri Aug 20 00:32:44 2010 -0400
     3.3 @@ -0,0 +1,46 @@
     3.4 +(ns clojureDemo.Defines)
     3.5 +
     3.6 +(import '(java.io File))
     3.7 +
     3.8 +(def -inf Double/NEGATIVE_INFINITY)
     3.9 +(def inf  Double/POSITIVE_INFINITY)
    3.10 +
    3.11 +
    3.12 +(def lian (File. "/home/r/Desktop/source-videos/lian1.mpeg"))
    3.13 +(def look (File. "/home/r/Desktop/source-videos/dramatic_look.flv"))
    3.14 +(def getto(File. "/home/r/Desktop/source-videos/Ghetto.flv"))
    3.15 +(def human0(File. "/home/r/Desktop/source-videos/vsr1/human0.avi"))
    3.16 +(def blow (File. "/home/r/Desktop/source-videos/blow.avi"))
    3.17 +
    3.18 +(def base (File. "/home/r/Desktop/source-videos/"))
    3.19 +
    3.20 +(def app0 (File. base "approach0v2.avi"))
    3.21 +(def app1 (File. base "approach1v3.avi"))
    3.22 +(def app2 (File. base "approach0v3.avi"))
    3.23 +(def app3 (File. base "approach2v2.avi"))
    3.24 +(def app4 (File. base "approach1v2.avi")) 
    3.25 +(def app5 (File. base "approach2v3.avi"))
    3.26 +  
    3.27 +(def bounce0 (File. base "bounce0v2.avi"))  
    3.28 +(def bounce1 (File. base "bounce1v3.avi")) 
    3.29 +(def bounce2 (File. base "bounce3v2.avi"))
    3.30 +(def bounce3 (File. base "bounce0v3.avi"))  
    3.31 +(def bounce4 (File. base "bounce2v2.avi"))
    3.32 +(def bounce5 (File. base "bounce1v2.avi"))  
    3.33 +(def bounce6 (File. base "bounce2v3.avi"))
    3.34 +
    3.35 +(def collide0 (File. base "collide0v3.avi"))  
    3.36 +(def collide1 (File. base "collide2v3.avi")) 
    3.37 +(def collide2 (File. base "collide1v2.avi"))
    3.38 +(def collide3 (File. base "collide0v2.avi"))  
    3.39 +(def collide4 (File. base "collide1v3.avi")) 
    3.40 +  
    3.41 +(def give0 (File. base "give0v3.avi"))  
    3.42 +(def give1 (File. base "give2v3.avi")) 
    3.43 +(def give2 (File. base "give1v2.avi")) 
    3.44 +(def give3 (File. base "give0v2.avi"))        
    3.45 +(def give4 (File. base "give1v3.avi"))
    3.46 +
    3.47 +
    3.48 +(def target (File. "/home/r/Desktop/output-vision/"))
    3.49 +(def default(File. target "default.avi"))
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/clojureDemo/FaceDetect.clj	Fri Aug 20 00:32:44 2010 -0400
     4.3 @@ -0,0 +1,70 @@
     4.4 +(ns clojureDemo.FaceDetect
     4.5 +  (:import (javax.swing JFrame JLabel Timer)
     4.6 +	   (java.awt.event ActionListener KeyAdapter)
     4.7 +	   (java.awt Canvas Image Color)
     4.8 +	   (java.awt.image MemoryImageSource)
     4.9 +	   (hypermedia.video OpenCV)))
    4.10 +
    4.11 +;this will not work with the current setup;
    4.12 +;it's just here as a reference for how to access
    4.13 +;cameras.
    4.14 +
    4.15 +(def frame-rate (int 1000/30))
    4.16 +(def width 640)
    4.17 +(def height 480)
    4.18 +
    4.19 +(defn vision []
    4.20 +  (doto (OpenCV.)
    4.21 +    (.capture width height)
    4.22 +    (.cascade OpenCV/CASCADE_FRONTALFACE_ALT)
    4.23 +))
    4.24 +
    4.25 +(defn capture-image [vis]
    4.26 +  (.read vis)
    4.27 +  (let [mis (MemoryImageSource. (.width vis) (.height vis)
    4.28 +				(.pixels vis) 0 (.width vis))]
    4.29 +    (.createImage (Canvas.) mis)))
    4.30 +
    4.31 +(defn detect-face [vis]
    4.32 +  (.detect vis 1.2 2 OpenCV/HAAR_DO_CANNY_PRUNING 20 20))
    4.33 +
    4.34 +(defn capture-action [vis panel image faces]
    4.35 +  (proxy [ActionListener] []
    4.36 +    (actionPerformed
    4.37 +     [e]
    4.38 +     (dosync (ref-set image (capture-image vis))
    4.39 +	     (ref-set faces (detect-face vis)))
    4.40 +     (.repaint panel))))
    4.41 +
    4.42 +(defn panel [image faces]
    4.43 +  (proxy [JLabel] [] 
    4.44 +    (paint
    4.45 +     [g]
    4.46 +     (.drawImage g @image 0 0 nil)
    4.47 +     (.setColor g Color/red)
    4.48 +     (doseq [square @faces]
    4.49 +       (.drawRect g
    4.50 +		  (.x square) (.y square)
    4.51 +		  (.width square) (.height square))))))
    4.52 +
    4.53 +(defn key-listener [vis timer]
    4.54 +  (proxy [KeyAdapter] [] 
    4.55 +    (keyReleased 
    4.56 +     [e]
    4.57 +     (.stop timer)
    4.58 +     (.dispose vis))))
    4.59 +
    4.60 +(defn main []
    4.61 +  (let [vis   (vision)
    4.62 +	image (ref (capture-image vis))
    4.63 +	faces (ref (detect-face vis))
    4.64 +	panel (panel image faces)
    4.65 +	timer (Timer. frame-rate (capture-action vis panel image faces))]
    4.66 +    (.start timer)
    4.67 +    (doto (JFrame.)
    4.68 +      (.add panel)
    4.69 +      (.addKeyListener (key-listener vis timer))
    4.70 +      (.setSize width height)
    4.71 +      (.show))))
    4.72 +
    4.73 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/clojureDemo/GenesisPlay.clj	Fri Aug 20 00:32:44 2010 -0400
     5.3 @@ -0,0 +1,501 @@
     5.4 +(ns clojureDemo.GenesisPlay)
     5.5 +
     5.6 +
     5.7 +(use 'clojure.contrib.import-static)
     5.8 +(import '(java.io File))
     5.9 +(import '(org.apache.commons.io FileUtils))
    5.10 +(import '(javax.imageio ImageIO) )
    5.11 +(import '(javax.swing JFrame))
    5.12 +(import '(java.awt Color BorderLayout))
    5.13 +(import '(ij.plugin PlugIn))
    5.14 +(import '(ij ImagePlus IJ))
    5.15 +(import '(java.lang Math))
    5.16 +
    5.17 +(use 'clojureDemo.appeture)
    5.18 +
    5.19 +(import-static java.lang.Math pow abs)
    5.20 +
    5.21 +(import '(ij Macro))
    5.22 +
    5.23 +(import '(java.io BufferedReader InputStreamReader))
    5.24 +(import '(java.awt.image BufferedImage))
    5.25 +(import '(genesis Genesis))
    5.26 +(import '(utils Mark))
    5.27 +(import '(capenLow StoryProcessor))
    5.28 +(import '(connections Connections WiredBox))
    5.29 +(import '(specialBoxes BasicBox MultiFunctionBox))
    5.30 +(import '(http Start))
    5.31 +(import '(engineering NewHardWiredTranslator))
    5.32 +
    5.33 +(import '(java.awt Polygon))
    5.34 +(import '(java.awt.geom Line2D$Double))
    5.35 +(use 'clojure.contrib.str-utils)
    5.36 +
    5.37 +
    5.38 +(use '[clojureDemo.Xuggle :only (video-seq trans-save flash display video-data)])
    5.39 +(use 'clojureDemo.MegaDeath)
    5.40 +
    5.41 +
    5.42 +(use 'clojure.contrib.combinatorics)
    5.43 +
    5.44 +(use 'clojure.contrib.repl-utils)
    5.45 +(use ['clojureDemo.Defines 
    5.46 +      :only '(
    5.47 +	     lian look getto human0 blow base app0 app1 app2 app3 app4 app5 
    5.48 +		  bounce0 bounce1 bounce2 bounce3 bounce4 bounce5 bounce6
    5.49 +		  collide0 collide1 collide2 collide3 collide4  
    5.50 +		  give0 give1 give2 give3 give4 target default)])
    5.51 +
    5.52 +
    5.53 +;(proxy 
    5.54 +
    5.55 +
    5.56 +
    5.57 +
    5.58 +
    5.59 +(defn startInFrame-rm 
    5.60 +  [genesis]
    5.61 +  (.start genesis)
    5.62 +  (let [frame (JFrame.)]
    5.63 +    (doto frame
    5.64 +      (.setTitle "Genesis")
    5.65 +      (.setBounds 0 0 1024 768)
    5.66 +      (doto (.getContentPane)
    5.67 +	(.setBackground Color/WHITE)
    5.68 +	(.setLayout (BorderLayout.))
    5.69 +	(.add genesis))
    5.70 +      (.setJMenuBar (.getMenuBar genesis))
    5.71 +      (.setVisible true))
    5.72 +    frame))
    5.73 +
    5.74 +
    5.75 +(defn run-genesis
    5.76 +  ([]  (startInFrame-rm (Genesis.)))
    5.77 +  ([genesis] (startInFrame-rm genesis)))
    5.78 +    
    5.79 +(defn lazy->hashMap
    5.80 +  [lazy]
    5.81 +   (zipmap  (map first lazy) (map last lazy)))
    5.82 +
    5.83 +(defn make-box
    5.84 +  "constructs a wired box sutiable for interfacing to Genesis"
    5.85 +  [name process-fn]
    5.86 +  (let [box (proxy [BasicBox] [] (getName [] name) 
    5.87 +		   (process [obj] (.transmit (Connections/getPorts this) (process-fn obj))))]
    5.88 +    (.addSignalProcessor (Connections/getPorts box) "process")
    5.89 +    box))
    5.90 +
    5.91 +
    5.92 +(defn make-generator-box
    5.93 +  "makes a box which only outputs a constant"
    5.94 +  [name constant]
    5.95 +  (let [box (proxy [BasicBox] []  (getName [] name) (process [obj] (.transmit (Connections/getPorts this) constant)))]    
    5.96 +    (.addSignalProcessor (Connections/getPorts box) "process")
    5.97 +    box))
    5.98 +
    5.99 +(defn naturals [] (iterate inc 0))
   5.100 +
   5.101 +;; ;(defn make-multifn-box [& args]
   5.102 +;; ;  (apply hash-map args)
   5.103 +  
   5.104 +;; ;  (map mega-macro naturals )
   5.105 +
   5.106 +;; ;  )
   5.107 +
   5.108 +
   5.109 +
   5.110 +
   5.111 +(defmacro function-name
   5.112 +  [function]
   5.113 +  (list str (list 'quote function)))
   5.114 +
   5.115 +(defn make-vision-box 
   5.116 +  "eventually I'll generalize this to arbitary functions and port names, but for now this is good enough"
   5.117 +  [function1 function2]
   5.118 +  (let [box (proxy [MultiFunctionBox] [] (getName [] "vision-box") 
   5.119 +		   (process1 [obj] (.transmit (Connections/getPorts this) (function1 obj)))
   5.120 +		   (process2 [obj] (.transmit (Connections/getPorts this) (function2 obj))))]
   5.121 +	(.addSignalProcessor (Connections/getPorts box) "PORT1" "process1")
   5.122 +	(.addSignalProcessor (Connections/getPorts box) "PORT2" "process2")
   5.123 +	box))
   5.124 +  
   5.125 +;; (defn make-box
   5.126 +;;   [name & functions]
   5.127 +;;   (let [box (proxy [MultiFunctionBox] [] (getName [] name)
   5.128 +;; 		   (for [indexed-fun  (clojure.contrib.seq-utils/indexed functions)] 
   5.129 +;; 		     ((symbol (str "process" (first indexed-fun))) 
   5.130 +;; 		      [obj] (.transmit (Connections/getPorts this) ((last indexed-fun) obj)))))]
   5.131 +    
   5.132 +;;     (for [indexed-fun  (clojure.contrib.seq-utils/indexed functions)] 
   5.133 +;;       (.addSignalProcessor (Connections/getPorts box) (str "PORT" (first indexed-fun))  (str "process" (first indexed-fun))))
   5.134 +;;     box))
   5.135 +
   5.136 +;; (defmacro proxy-functions
   5.137 +;;   [ name & functions]
   5.138 +;; (into
   5.139 +;;  (for [indexed-fun  (clojure.contrib.seq-utils/indexed functions)] 
   5.140 +;;    (list (symbol (str "process" (first indexed-fun))) (vector 'obj)  
   5.141 +;; 	 (list '.transmit '(Connections/getPorts this) (list (last indexed-fun) 'obj))))
   5.142 +;;  (list  (list 'getName (vector) name)   (vector) (vector MultiFunctionBox) 'proxy)))
   5.143 +   
   5.144 +
   5.145 +
   5.146 +;; 		     ((symbol (str "process" (first indexed-fun))) 
   5.147 +;; 		      [obj] (.transmit (Connections/getPorts this) ((last indexed-fun) obj)))))
   5.148 +
   5.149 +;; (defmacro make-fun2-box
   5.150 +;;   [name & functions]
   5.151 +  
   5.152 +
   5.153 +
   5.154 +;; (defmacro make-fun-box
   5.155 +;;   [name & functions]
   5.156 +;;   (let [proxy-functions 
   5.157 +;; 	(for [indexed-fun  (clojure.contrib.seq-utils/indexed functions)]
   5.158 +;; 	   ((symbol (str "process" (first indexed-fun)))
   5.159 +;; 		      [`obj#] (.transmit (Connections/getPorts 'this) ((last indexed-fun) `obj#))))]
   5.160 +    
   5.161 +
   5.162 +  
   5.163 +;;   `(let [box# (proxy [MultiFunctionBox] [] (getName [] ~name))]
   5.164 +;;      ~proxy-functions     
   5.165 +;;     box#))
   5.166 +
   5.167 +;; (defmacro return
   5.168 +;;   [name & functions]
   5.169 +;;   (let [out (for [x functions]
   5.170 +;;     x)]
   5.171 +;;      out))
   5.172 +
   5.173 +  
   5.174 +
   5.175 +		   
   5.176 +
   5.177 +(defn local-genesis
   5.178 +  "connects the custom vision interperter to genesis"
   5.179 +  [function1 function2]
   5.180 +  (let [vision-box (make-vision-box function1 function2) genesis (Genesis.) ]
   5.181 +    (Connections/wire Start/TRIPLES (.getStartParser genesis) "PORT1" vision-box)
   5.182 +    (Connections/wire NewHardWiredTranslator/RESULT (.getNewSemanticTranslator genesis) "PORT2" vision-box)
   5.183 +    genesis))
   5.184 +
   5.185 +
   5.186 +
   5.187 +
   5.188 +
   5.189 +
   5.190 +(defn frame-hash
   5.191 +  "yields a convienent representation for the pixles in an image.
   5.192 +   Because of the size of the structvre generated, this must only be used
   5.193 +   in a transient way so that java can do it's garbage collection."
   5.194 +  [imagePlus]
   5.195 +  (with-meta
   5.196 +  (let [buf (.. imagePlus getBufferedImage)
   5.197 +	color (.getColorModel buf)]
   5.198 +   (doall (apply hash-map 
   5.199 +	   (interleave 
   5.200 +	    (doall (for [x (range (.getWidth imagePlus)) y (range (.getHeight imagePlus))]
   5.201 +	      (vector x y)))
   5.202 +	    (doall (for [x (range (.getWidth imagePlus)) y (range (.getHeight imagePlus))]
   5.203 +	     (let [data (.getRGB buf x y)] 
   5.204 +	      (hash-map :r (bit-shift-right (bit-and 0xff0000 data) 16)
   5.205 +			:g (bit-shift-right (bit-and 0x00ff00 data) 8)
   5.206 +			:b (bit-and 0x0000ff data)))))))))
   5.207 +  {:width  (.getWidth imagePlus) :height (.getHeight imagePlus)}))
   5.208 +
   5.209 +
   5.210 +
   5.211 +(defn vid-seq
   5.212 +  [video]
   5.213 +  (with-meta (doall (map frame-hash (video-seq video))) (video-data video)))
   5.214 +
   5.215 +
   5.216 +
   5.217 +
   5.218 +
   5.219 +(defn video-hash
   5.220 +  "turns an entire video into a nice hash-map
   5.221 +   .... or at least it would, if java didn't suck and only give me 
   5.222 +   2 GB to work with with no way to increase it.
   5.223 +   linear processing... grumble grumble ....."
   5.224 +  [video-seq]
   5.225 +  (apply hash-map
   5.226 +	 (interleave
   5.227 +	  (naturals)
   5.228 +	  (doall (map #(frame-hash %) video-seq)))))
   5.229 +	   
   5.230 +
   5.231 +
   5.232 +
   5.233 +(defn frame-hash->bufferedImage
   5.234 +  [frame-hash]
   5.235 +    (let [data  (meta frame-hash)
   5.236 +	image (BufferedImage. (:width data) (:height data) BufferedImage/TYPE_INT_BGR)]
   5.237 +	
   5.238 +	(doall (for [element frame-hash] 
   5.239 +	  (let [coord  (key element) 
   5.240 +		rgb   (val element)
   5.241 +		packed-RGB 
   5.242 +		(+ (bit-shift-left (:r rgb) 16)
   5.243 +		   (bit-shift-left (:g rgb) 8)
   5.244 +		                   (:b rgb))]
   5.245 +	    (.setRGB image (first coord) (last coord) packed-RGB))))
   5.246 +	image))
   5.247 +
   5.248 +(defmethod display
   5.249 +  clojure.lang.PersistentHashMap [frame-hash]
   5.250 +  (display (frame-hash->bufferedImage frame-hash)))
   5.251 +
   5.252 + (defmethod display
   5.253 +   clojure.lang.PersistentArrayMap [frame-hash]
   5.254 +   (display (frame-hash->bufferedImage frame-hash)))
   5.255 +
   5.256 +;; (defmethod display 
   5.257 +;;    clojure.lang.LazySeq [frame-hash]
   5.258 +;;   (display (frame-hash->bufferedImage frame-hash)))
   5.259 +
   5.260 +
   5.261 +
   5.262 +
   5.263 +
   5.264 +(defn rectangle-window
   5.265 +  "efficiently grabs a rectangle from the frame-hash.
   5.266 +   Values that don't exisist in the picture are colored negative green!"
   5.267 +  [x y l w frame-hash]
   5.268 +  (let [coords (for [m (range (- x l) (+ 1 x l)) n (range (- y w) ( + 1 y w))] (vector m n))]
   5.269 +
   5.270 +    (with-meta
   5.271 +      (zipmap
   5.272 +       coords
   5.273 +       (map #(frame-hash % {:r 0 :g -500 :b 0}) coords))   
   5.274 +      (meta frame-hash))))
   5.275 +
   5.276 +
   5.277 +(defn sum 
   5.278 +     "squashes all the dinensions of the picture together into a single dimension
   5.279 +      sutiable for analysis."
   5.280 +     [window]
   5.281 +     (zipmap
   5.282 +      (keys window)
   5.283 +      (map (fn [rgb] (+ (:r rgb) (:b rgb) (:g rgb))) (vals window))))
   5.284 +
   5.285 +(defn b&w
   5.286 +  "turn everything grey"
   5.287 +  [window]
   5.288 +  (with-meta
   5.289 +  (zipmap
   5.290 +   (keys window)
   5.291 +   (map (fn  [rgb] 
   5.292 +	  (let [sum (int (/ (+ (:r rgb) (:b rgb) (:g rgb)) 3))]
   5.293 +	    {:r sum :g sum :b sum })) (vals window))) (meta window)))
   5.294 +
   5.295 +(defn green-select-x-form
   5.296 +  "find green things"
   5.297 +  [window]
   5.298 +  (with-meta
   5.299 +  (zipmap
   5.300 +   (keys window)
   5.301 +   (map (fn  [rgb] 
   5.302 +	  (if (and (> (:g rgb) (:b rgb)) (> (:g rgb) (:r rgb)))
   5.303 +	    rgb
   5.304 +	    {:r 0 :g 0 :b 0})) (vals window))) (meta window)))
   5.305 +  
   5.306 +
   5.307 +(defn manual-line-detect
   5.308 +  "Ty as I might, this can never be truly effective until higher level
   5.309 +   processes contribute to dynamicaly adjusting these paramaters. For
   5.310 +   now I'll settle with simple manual calibration."
   5.311 +  [var1 mean1 var2 mean2]
   5.312 +  (> 
   5.313 +  (if (or (< var1 250) (< var2 250))
   5.314 +    (abs (int (- mean1 mean2)))
   5.315 +    0) 55))
   5.316 +;30 looks good
   5.317 +
   5.318 +
   5.319 +
   5.320 +
   5.321 +(defn frame-windows
   5.322 +  "analyzes a frame in terms of lots of tiny windows which 
   5.323 +   each try to find some sort of edge."
   5.324 +  ([ x-form frame]
   5.325 +     (with-meta
   5.326 +     (let [width (:width  (meta frame) 500)
   5.327 +	   height(:height (meta frame) 500 )]
   5.328 +       (filter (comp not nil?) 
   5.329 +	       (for [x (range 0 width 2) y (range 0 height 2)]
   5.330 +		 (:line (window-line (rectangle-window x y 1 1 frame) (comp sum x-form) manual-line-detect))))) (meta frame)))
   5.331 +  ([frame]  (frame-windows identity frame)))
   5.332 +
   5.333 +
   5.334 +(defn static-segmentation
   5.335 +  "divides a single picture frame into appropiate objects using a 
   5.336 +   simple watershed method based on sharp color variation.
   5.337 +   radius: the general size of the window in pixels
   5.338 +   gradient: threshold for a color gradient to be recognized as a edge"
   5.339 +  [radius gradient frame]
   5.340 +  (let [ah (frame-hash frame)]
   5.341 +    ah))
   5.342 +
   5.343 +
   5.344 +(defn video-parse
   5.345 +  "this is the equilivalent to the S.T.A.R.T Parser for videos
   5.346 +      right now it's just a simple blob detector"
   5.347 +  [video-seq]
   5.348 +  
   5.349 +  )
   5.350 +
   5.351 +
   5.352 +
   5.353 +(defn overlay-draw
   5.354 + [frame-hash overlay]
   5.355 + (let [image  (frame-hash->bufferedImage frame-hash)
   5.356 +       g2 (.getGraphics image)]
   5.357 +   (doall (for [ x overlay] 
   5.358 +     (let [x1 (ffirst x) y1 (second (first x)) x2 (first (last x)) y2 (last (last x))] 
   5.359 +       (.drawLine g2 x1 y1 x2 y2))))
   5.360 +     image))
   5.361 +
   5.362 +
   5.363 +
   5.364 +(defn video-seq->b&w
   5.365 +  [video-seq]
   5.366 +  (with-meta
   5.367 +    (map #(ImagePlus. "B and W" (frame-hash->bufferedImage %))
   5.368 +
   5.369 +    (map (fn [imgPlus]
   5.370 +	   (let [play (frame-hash imgPlus)]
   5.371 +	     (b&w play)))
   5.372 +	 video-seq))
   5.373 +    (meta video-seq)))
   5.374 +
   5.375 +
   5.376 +
   5.377 +(defn vid-save
   5.378 +  [filename vid-seq]
   5.379 +  (trans-save filename 
   5.380 +	     (with-meta (map (comp #(ImagePlus. "reverse-x-form" %)  frame-hash->bufferedImage) vid-seq) (meta vid-seq))))
   5.381 + 
   5.382 +
   5.383 +
   5.384 +;(def g0 (video-seq give0))
   5.385 +(def gen (proxy [Genesis] [] ))
   5.386 +(def short-give  (with-meta (take 60 (drop 30 (video-seq give0))) {:fps 30 :width 320 :height 240 }))
   5.387 +
   5.388 +(def sg short-give)
   5.389 +(def g1 (first sg))
   5.390 +(def gs sg)
   5.391 +(def play  (frame-hash (first sg)))
   5.392 +(def blank (with-meta (zipmap (keys play) (repeat (count play) {:r 0 :g 0 :b 0})) (meta play)))
   5.393 +
   5.394 +(def blank (with-meta (zipmap (keys play) (repeat (count play) {:r 0 :g 0 :b 0})) (meta play)))
   5.395 +(def b+w-play (b&w play))
   5.396 +(def rgb (rectangle-window 50 50 1 1 play))
   5.397 +(def invertedPlay (with-meta (zipmap (keys play) (map #(hash-map :r (- 255 (:r %)) :g (- 255 (:g %)) :b (- 255 (:b %))) (vals b+w-play))) (meta play)))
   5.398 +
   5.399 +(def invertedColorPlay (with-meta (zipmap (keys play) (map #(hash-map :r (- 255 (:r %)) :g (- 255 (:g %)) :b (- 255 (:b %))) (vals play))) (meta play)))
   5.400 +
   5.401 +(def play1 (with-meta (frame-hash (nth sg 0)) {:width 320 :height 240}))
   5.402 +(def play2 (with-meta (frame-hash (nth sg 1)) {:width 320 :height 240}))
   5.403 +(def play3 (with-meta (frame-hash (nth sg 2)) {:width 320 :height 240}))
   5.404 +(def play4 (with-meta (frame-hash (nth sg 3)) {:width 320 :height 240}))
   5.405 +(def play5 (with-meta (frame-hash (nth sg 4)) {:width 320 :height 240}))
   5.406 +
   5.407 +
   5.408 +
   5.409 +
   5.410 +
   5.411 +
   5.412 +
   5.413 +
   5.414 +
   5.415 +
   5.416 +
   5.417 +
   5.418 +
   5.419 +
   5.420 +
   5.421 +
   5.422 +
   5.423 +
   5.424 +
   5.425 +
   5.426 +
   5.427 +
   5.428 +
   5.429 +
   5.430 +
   5.431 +
   5.432 +(comment
   5.433 +  ok here's the plan--
   5.434 +
   5.435 +  "genesis/language"
   5.436 +  raw text -> START -> representations/memory -> story tree
   5.437 +  
   5.438 +  "genesis/vision"
   5.439 +  raw video -> blob detector -> representations/memory -> event/structure tree
   5.440 +
   5.441 +  first, we start off with a video.
   5.442 +  the video get's passed through the blob detector.
   5.443 +  
   5.444 +  (blob-detector 
   5.445 +   first-pass-  divide up each frame into exasutive polygons. no temporal dependence
   5.446 +   second-pass- do a pairwise comparison of frames to link the polygons from each frame.
   5.447 +                polygons can either split apart or merge, but this step establishes their geneology.
   5.448 +   third-pass-  link the polygons together into higher objects using hueristic rules about motion
   5.449 +                these rules are determined by the language system, but for now they will be hardcoded.
   5.450 +                the only thing for now is that things that move together are the same object.
   5.451 +  )
   5.452 +
   5.453 +
   5.454 +  so now, we have a temporal history of polygons.
   5.455 +  the language part of the story may specify that certain characters
   5.456 +  with certain qualities do certain actions. 
   5.457 +  
   5.458 +  "Bob is wearing a red shirt. Shirts are big. Bob is a person.
   5.459 +   Mary is wearing a green shirt.
   5.460 +   Bob is person-sized.
   5.461 +   Bob is moving.
   5.462 +   The green object is a ball.
   5.463 +   Bob gives the ball to Mary."
   5.464 +
   5.465 +  Now, Genesis can select just the polygons that are important to the story,
   5.466 +  and it also learns important facts such as the relative size of a person to a ball.
   5.467 +
   5.468 +  The details which are captured in the polygon-transition space are--
   5.469 +  x (location of the center of each polygon), dx/dt , ((d^2)x)/(dt)^2, color (average), [left|right], polygon area
   5.470 +  polygon shape
   5.471 +  
   5.472 +  This information recurses on every component polygon as well.
   5.473 +
   5.474 +  When genesis want's to learn about verbs in particular, 
   5.475 +  it selects the aproapiate blobs from the linguistic desctiption (in bob's
   5.476 +  case it's "the big red blob on the left", for example.)
   5.477 +
   5.478 +  after selecting a subset of the blobs, it calculates the angles and distances between 
   5.479 +  those blobs' centers as erll as whether they are touching or overlaping.
   5.480 +
   5.481 +  From this sequence it derives an example of the verb.
   5.482 +
   5.483 +  From other examples it can do arch earning to refine the sequence to its salient features.
   5.484 + )
   5.485 +  
   5.486 +
   5.487 +
   5.488 +(comment (things you can do that will actually work!)
   5.489 +
   5.490 +(do (use :reload-all 'clojureDemo.GenesisPlay) (in-ns 'clojureDemo.GenesisPlay))
   5.491 +;genesis integration:
   5.492 +(def gen5 (make-generator-box "the 5th element" 5))
   5.493 +(Connections/wire gen5 (make-box "printer" println))
   5.494 +(Connections/viewNetwork)
   5.495 +(.process gen5 :ignore) ; causes 5 to be printed
   5.496 +(Connections/obliterateNetwork)
   5.497 +(.process gen5 :ignore); since the network connections were dissolved, nothing prints.
   5.498 +
   5.499 +
   5.500 +
   5.501 +)
   5.502 +
   5.503 +
   5.504 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/clojureDemo/ImageJ.clj	Fri Aug 20 00:32:44 2010 -0400
     6.3 @@ -0,0 +1,12 @@
     6.4 +(ns clojureDemo.ImageJ)
     6.5 +
     6.6 +
     6.7 +
     6.8 +
     6.9 +(comment 
    6.10 +
    6.11 +(do (use :reload-all 'clojureDemo.ImageJ) (in-ns 'clojureDemo.ImageJ))
    6.12 +
    6.13 +1255231 for non delayed version.
    6.14 +
    6.15 +)
     7.1 Binary file src/clojureDemo/LocalGenesis.class has changed
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/clojureDemo/MegaDeath.clj	Fri Aug 20 00:32:44 2010 -0400
     8.3 @@ -0,0 +1,90 @@
     8.4 +(ns clojureDemo.MegaDeath)
     8.5 +
     8.6 +(import '(java.io File))
     8.7 +(import '(org.apache.commons.io FileUtils))
     8.8 +(import '(javax.imageio ImageIO) )
     8.9 +
    8.10 +(import '(ij.plugin PlugIn))
    8.11 +(import '(ij ImagePlus IJ))
    8.12 +
    8.13 +(import '(ij Macro))
    8.14 +
    8.15 +(import '(java.io BufferedReader InputStreamReader))
    8.16 +(import '(java.awt.image BufferedImage))
    8.17 +
    8.18 +
    8.19 +
    8.20 +(use '[clojureDemo.Xuggle :only (video-seq trans-save flash video-data display)])
    8.21 +
    8.22 +
    8.23 +(use 'clojure.contrib.repl-utils)
    8.24 +(use ['clojureDemo.Defines 
    8.25 +      :only '(
    8.26 +	     lian look getto human0 blow base app0 app1 app2 app3 app4 app5 
    8.27 +		  bounce0 bounce1 bounce2 bounce3 bounce4 bounce5 bounce6
    8.28 +		  collide0 collide1 collide2 collide3 collide4  
    8.29 +		  give0 give1 give2 give3 give4 target default)])
    8.30 +
    8.31 +
    8.32 +(def hamster  (first (video-seq look)))
    8.33 +(def ham (.getImage hamster))
    8.34 +
    8.35 +(set! *print-length* 10)
    8.36 +
    8.37 +
    8.38 +
    8.39 +(defn final-ficker
    8.40 +  "wtf?"
    8.41 +  [& vars]
    8.42 +  (class (last vars)))
    8.43 +
    8.44 +(defmulti log-polar (fn [& args] (class (last args))))
    8.45 +
    8.46 +(defmethod log-polar clojure.lang.LazySeq
    8.47 +  ([X Y video-seq]
    8.48 +     (with-meta (map #(log-polar % X Y) video-seq) (meta video-seq)))
    8.49 +  ([video-seq]
    8.50 +     (with-meta (map #(log-polar %) video-seq) (meta video-seq))))
    8.51 +
    8.52 +
    8.53 +(defmethod log-polar ij.ImagePlus
    8.54 +     [imageP]
    8.55 +     (let [thread (Thread/currentThread)
    8.56 +	   options ""]
    8.57 +       (.setName thread "Run$_polar-transform")
    8.58 +       (Macro/setOptions thread options)
    8.59 +       (IJ/runPlugIn imageP "clojureDemo.Polar_Transformer" "")
    8.60 +       (let [return-image (IJ/getImage)]
    8.61 +	 (.hide return-image)
    8.62 +	 return-image)))
    8.63 +
    8.64 +(defn x-polar2 
    8.65 +     [imageP]
    8.66 +     (let [thread (Thread/currentThread)
    8.67 +	   options ""]
    8.68 +       (.setName thread "Run$_polar-transform")
    8.69 +       (Macro/setOptions thread options)
    8.70 +       (IJ/runPlugIn imageP "clojureDemo.Polar_Transformer" "")))
    8.71 +
    8.72 +
    8.73 +
    8.74 +(defn follow-object
    8.75 +     "takes in a video stream and does the most basic and simple forms of object detection."
    8.76 +     [video-seq]
    8.77 +)
    8.78 +
    8.79 +
    8.80 +
    8.81 +
    8.82 +
    8.83 +
    8.84 +
    8.85 +
    8.86 +
    8.87 +
    8.88 +
    8.89 +(comment
    8.90 +
    8.91 +(do (use :reload-all 'clojureDemo.MegaDeath) (in-ns 'clojureDemo.MegaDeath))
    8.92 +(map #(ns-unmap 'user %)(keys (ns-interns 'user)))
    8.93 +)
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/clojureDemo/OpenCv.clj	Fri Aug 20 00:32:44 2010 -0400
     9.3 @@ -0,0 +1,226 @@
     9.4 +(ns clojureDemo.OpenCv)
     9.5 +  
     9.6 +(import '(java.awt Rectangle Robot Toolkit) )
     9.7 +(import '(java.awt.image BufferedImage) )
     9.8 +(import '(java.awt Graphics2D Panel))
     9.9 +(import '(java.io File) )
    9.10 +(import '(javax.imageio ImageIO) )
    9.11 +(import '(javax.swing JFrame))
    9.12 +(import '(org.apache.commons.io FileUtils))
    9.13 +(import clojure.lang.LazySeq)
    9.14 +(import '(name.audet.samuel.javacv.jna highgui cv cxcore 
    9.15 +				       cxcore$IplImage highgui$CvCapture$PointerByReference  
    9.16 +				       highgui$CvVideoWriter$PointerByReference cxcore$IplImage$PointerByReference))
    9.17 +(import '(name.audet.samuel.javacv CanvasFrame JavaCvErrorCallback))
    9.18 +
    9.19 +(.redirectError (JavaCvErrorCallback.))
    9.20 +
    9.21 +(use 'clojure.contrib.repl-utils)
    9.22 +;(use 'clojureDemo.Defines)
    9.23 +;(use '[clojureDemo.Xuggle :only (cache)])
    9.24 +
    9.25 +;this is still a work in progress, I'll come back to it later when I understand 
    9.26 +;jna more thoroughly.  the important abstraction here is 
    9.27 +;video-seq, which gives a lazy sequence of Intel Image Processing library images.
    9.28 +
    9.29 +(defn naturals [] (iterate inc 0))
    9.30 +
    9.31 +(defn- makePanel [image] (proxy [Panel] [] (paint [g]  (.drawImage g image 0 0 nil))))
    9.32 +
    9.33 +
    9.34 +(defmulti  display "Creates a JFrame and displays a buffered image"  class)
    9.35 +
    9.36 +(defmethod display 
    9.37 +  BufferedImage  [image] 
    9.38 +  (let [panel (makePanel image)
    9.39 +	frame (JFrame. "Oh Yeah!")]
    9.40 +    (.add frame panel) 
    9.41 +    (.pack frame) 
    9.42 +    (.setVisible frame true ) 
    9.43 +    (.setSize frame(.getWidth image) (.getHeight image))))
    9.44 +
    9.45 +(defmethod display
    9.46 +  cxcore$IplImage [image]
    9.47 +  ( display (.getBufferedImage image)))
    9.48 +  
    9.49 +(defmethod display
    9.50 +  String [image]
    9.51 +  (display (highgui/cvLoadImage image highgui/CV_LOAD_IMAGE_COLOR)))
    9.52 +
    9.53 +(defmethod display
    9.54 +  LazySeq [s]
    9.55 +  (display (first s)))
    9.56 +
    9.57 +
    9.58 +
    9.59 +(def ext "jpg") 
    9.60 +;see below for the rationale for this choice of extention.
    9.61 +
    9.62 +(def cache-location "/home/r/Desktop/vision-cache/")
    9.63 +
    9.64 +(defn close-capture
    9.65 +  [capture]
    9.66 +  (highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture)))
    9.67 +
    9.68 +(defn close-writer
    9.69 +  [writer] (highgui/cvReleaseVideoWriter (highgui$CvVideoWriter$PointerByReference. writer))) 
    9.70 +
    9.71 +(defn- cache-path
    9.72 +  [video]
    9.73 +  (File. cache-location (.getName video)))
    9.74 +
    9.75 +(defn- already-cached
    9.76 +  "this is the simplest and most retarded way to do it"
    9.77 +  [video]
    9.78 +  (.exists (cache-path video)))
    9.79 +
    9.80 +(defn write-frame 
    9.81 +  [capture target-dir n]
    9.82 +  (let [image (highgui/cvQueryFrame capture)]
    9.83 +    (if (nil? image) false
    9.84 +	(highgui/cvSaveImage (str (File. target-dir (str n "."  ext))) image))))
    9.85 +
    9.86 +(defn- write-frame-bad
    9.87 +  [capture target-dir n]
    9.88 +  (println (str "saving frame: " n))
    9.89 +  (let [image (highgui/cvQueryFrame capture)]
    9.90 +    (if (nil? image) false
    9.91 +	( ImageIO/write (.getBufferedImage image) ext (File. target-dir (str n "."  ext))))))
    9.92 +
    9.93 +(defn- write-frames
    9.94 +  [video target-dir]
    9.95 +  (let [capture (highgui/cvCreateFileCapture (.getPath video))]
    9.96 +   (dorun 
    9.97 +    (for [n (naturals) :while (write-frame capture target-dir n) ] nil ))
    9.98 +    (highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture))))
    9.99 +
   9.100 +(defn- cache-frames
   9.101 +  [cache-location video]
   9.102 +  (time 
   9.103 +   (do
   9.104 +     (println "\"caching entire video structure... this will take a while... go get a snack or something :)\"")
   9.105 +     (FileUtils/deleteDirectory (cache-path video))
   9.106 +     (FileUtils/forceMkdir (cache-path video))
   9.107 +     (write-frames video  (cache-path video)))))
   9.108 +
   9.109 +;(defn cache
   9.110 +;  [video]
   9.111 +;  (if (already-cached video) nil (cache-frames cache-location video)))
   9.112 + 
   9.113 +(defn video-len 
   9.114 +  [video]
   9.115 +  (alength (.list (cache-path video))))
   9.116 +(def video-len (memoize video-len))
   9.117 + 
   9.118 +(defn video-data
   9.119 +  "since the opencv version is so absolutely unreliable..."
   9.120 +  [video]
   9.121 +  (let
   9.122 +      [capture (highgui/cvCreateFileCapture (.getPath video))
   9.123 +       info {:length      (video-len video)
   9.124 +	     :width       (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FRAME_WIDTH)
   9.125 +	     :height      (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FRAME_HEIGHT)
   9.126 +	     :fps         (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FPS)
   9.127 +	     :codec       (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FOURCC)}]
   9.128 +    (close-capture capture)
   9.129 +    info))
   9.130 +(def video-data (memoize video-data))
   9.131 +
   9.132 +(defn video-frame-path
   9.133 +     [video n]
   9.134 +     (File. (cache-path video)  (str n "."  ext)))
   9.135 +
   9.136 +
   9.137 +(defn- video-frame-ipl
   9.138 +  [video n] 
   9.139 +;  (cache video)
   9.140 +  (let 
   9.141 +      [c++-managed  (highgui/cvLoadImage (str (File. (cache-path video) (str n "."  ext))) highgui/CV_LOAD_IMAGE_COLOR)
   9.142 +       jvm-managed (.clone c++-managed)] 
   9.143 +	 ;this bit with the cloning is so I can deal with Garbage Collection once and for all.
   9.144 +	 ;the cpp-managed image must be manually Garbage Collected, but it's clone is managed by 
   9.145 +         ;the JVM's Garbage Collector.  By getting rid of the c++ part right here and now, no 
   9.146 +         ;other function has to worry about manual garbage collection ever again.
   9.147 +         ;Unfortunately, this doesn't seem to work for certain types of files. It's not file-size
   9.148 +         ;which is the issue, but something involving the image header.
   9.149 +    (cxcore/cvReleaseImage (.pointerByReference c++-managed))
   9.150 +    jvm-managed
   9.151 +))
   9.152 +  
   9.153 +
   9.154 +(defn- video-frame-buffered
   9.155 +  "takes one frame from a video in constant time"
   9.156 +  [video n]
   9.157 + ; (cache video)
   9.158 +  (ImageIO/read (File. (cache-path video) (str n "."  ext))))
   9.159 +
   9.160 +(defn video-frame [video n] (video-frame-buffered video n))
   9.161 +
   9.162 +(defn- dumb-write 
   9.163 +  [video n writer]
   9.164 +  (let 
   9.165 +      [c++-managed  (highgui/cvLoadImage (str (File. (cache-path video) (str n ext))) highgui/CV_LOAD_IMAGE_COLOR)]
   9.166 +    (highgui/cvWriteFrame writer  c++-managed)
   9.167 +    (cxcore/cvReleaseImage (cxcore$IplImage$PointerByReference. c++-managed))))
   9.168 +
   9.169 +(defn video-seq
   9.170 +  "makes a lazy sequence of IPL images"
   9.171 +  ;additionally, I want to pass metadata around with the sequence.
   9.172 +  [video] ;(cache video)
   9.173 +  (map #(video-frame video %) (range (video-len video))))
   9.174 +(defn video-writer
   9.175 +  "uses data about the video to make a writer"
   9.176 +  [data fileTarget]
   9.177 +  (highgui/cvCreateVideoWriter 
   9.178 +   (str fileTarget)
   9.179 +   
   9.180 +   ;(highgui/CV_FOURCC \P,\I,\M,\1) ;= MPEG-1 codec  (112913.386195 msecs) (104 MB)
   9.181 +   ;(highgui/CV_FOURCC \M,\J,\P,\G) ;= motion-jpeg codec (crashed)
   9.182 +   ;(highgui/CV_FOURCC \M,\P,\4,\2) ;= MPEG-4.2 codec (107184.186774 msecs) (82 MB)
   9.183 +   ;(highgui/CV_FOURCC \D,\I,\V,\3) ;= MPEG-4.3 codec (118308.933328 msecs)  (83 MB)
   9.184 +   (highgui/CV_FOURCC \D,\I,\V,\X) ;= MPEG-4 codec    (99037.738131 msecs)  (85 MB)
   9.185 +   ;(highgui/CV_FOURCC \U,\2,\6,\3) ;= H263 codec     (101141.993551 msecs) (89 MB)
   9.186 +   ;(highgui/CV_FOURCC \I,\2,\6,\3) ;= H263I codec      (crashed)
   9.187 +   ;(highgui/CV_FOURCC \F,\L,\V,\1) ;= FLV1 codec     (104307.567802 msecs) (93 MB)
   9.188 +   ;(:codec data)                    ;= whatever the movie originally had.  (98278.694169 msecs) (1.9 GB)  
   9.189 +
   9.190 +   (:fps data) (cxcore/cvSize (:width data) (:height data)) 
   9.191 +   1; 1 here means that we're writing in color.
   9.192 +    ; you cannot change it to 0 to write in 
   9.193 +    ; black and white. Everything just crashes instead.
   9.194 +    ; what a useful paramater.
   9.195 +   ))
   9.196 +
   9.197 +
   9.198 +(defn naturals []  (iterate inc 0))
   9.199 +
   9.200 +
   9.201 +(defn write-frame-2
   9.202 +  [writer frame]
   9.203 +  (let [c++-frame (cxcore$IplImage/createFrom frame)]
   9.204 +    (highgui/cvWriteFrame writer c++-frame)
   9.205 +   ; (cxcore/cvReleaseImage (.pointerByReference c++-frame)))
   9.206 +)
   9.207 +    frame)
   9.208 +
   9.209 +(defn save-seq 
   9.210 +  [writer video-seq]
   9.211 +  (map #(write-frame-2 writer %) video-seq))
   9.212 +
   9.213 +(defmacro trans-save
   9.214 +"there's a small problem with trans-save --- it IS
   9.215 +truly transitive, but it does too much work....
   9.216 +sometimes it writes files twice.
   9.217 +this is functionally correct though."
   9.218 +  [target config video-seq]
   9.219 +  `(let [writer# (video-writer ~config ~target)]
   9.220 +     (do
   9.221 +       (dorun (save-seq writer# ~video-seq))
   9.222 +       (close-writer writer#)
   9.223 +       ~video-seq)))
   9.224 +
   9.225 +
   9.226 +
   9.227 +(comment 
   9.228 +(do (use :reload-all 'clojureDemo.OpenCv) (in-ns 'clojureDemo.OpenCv))
   9.229 +)
    10.1 Binary file src/clojureDemo/Polar_Transformer.class has changed
    11.1 Binary file src/clojureDemo/ScracthPad.class has changed
    12.1 Binary file src/clojureDemo/TestNetwork.class has changed
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/clojureDemo/VideoParse.clj	Fri Aug 20 00:32:44 2010 -0400
    13.3 @@ -0,0 +1,230 @@
    13.4 +(ns clojureDemo.VideoParse)
    13.5 +  
    13.6 + 
    13.7 +
    13.8 +;this file is not used anymore, except for the (display %) function.
    13.9 +
   13.10 +
   13.11 +
   13.12 +(import '(java.awt Rectangle Robot Toolkit) )
   13.13 +(import '(java.awt.image BufferedImage) )
   13.14 +(import '(java.awt Graphics2D Panel))
   13.15 +(import '(java.io File) )
   13.16 +(import '(javax.imageio ImageIO) )
   13.17 +(import '(com.xuggle.mediatool ToolFactory))
   13.18 +(import '(com.xuggle.mediatool IMediaDebugListener IMediaDebugListener$Event))
   13.19 +(import '(com.xuggle.mediatool MediaToolAdapter))
   13.20 +(import '(com.xuggle.xuggler IContainer IContainer$Type IPacket))
   13.21 +(import '(javax.swing JFrame))
   13.22 +
   13.23 +(import clojure.lang.LazySeq)
   13.24 +
   13.25 +(import '(name.audet.samuel.javacv.jna highgui cv cxcore))
   13.26 +
   13.27 +(import '(name.audet.samuel.javacv CanvasFrame))
   13.28 +
   13.29 +(import '(name.audet.samuel.javacv.jna cxcore$IplImage))
   13.30 +
   13.31 +(import '(name.audet.samuel.javacv.jna highgui$CvCapture$PointerByReference))
   13.32 +(import '(name.audet.samuel.javacv.jna highgui$CvVideoWriter$PointerByReference))
   13.33 +
   13.34 +;definitions
   13.35 +
   13.36 +(def -inf Double/NEGATIVE_INFINITY)
   13.37 +(def inf  Double/POSITIVE_INFINITY)
   13.38 +
   13.39 +(use 'clojure.contrib.repl-utils)
   13.40 +
   13.41 +
   13.42 +;minor functions
   13.43 +
   13.44 +(defn converge
   13.45 +  "recursively runs update until prior passes accept, then returns"
   13.46 +  [prior update accept]
   13.47 +  (if (accept prior) prior (recur (update prior) update accept)))
   13.48 +
   13.49 +(defn interval-width [interval] (- (last interval) (first interval)))
   13.50 +
   13.51 +(defn midpoint [interval] 
   13.52 +  (let [a (first interval) b (last interval)]
   13.53 +    (if (and (= a -inf) (= b inf)) 0
   13.54 +    (if (= a -inf) (midpoint [(- b 200000) b])
   13.55 +	(if (= b inf) (midpoint [a (+ a 200000)])
   13.56 +	    (int (/ (+ a b) 2)))))))
   13.57 +
   13.58 +(defn cart2
   13.59 +  "calculates the cartesian product in 2 dimensions"
   13.60 +  [point] 
   13.61 +  (let [[x y] point] (for [abscissa (range x) ordinate (range y)] [abscissa ordinate])))
   13.62 +
   13.63 +(defn closeCapture
   13.64 +  [capture]
   13.65 +  (highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture)))
   13.66 +
   13.67 +(defn- makePanel [image] (proxy [Panel] [] (paint [g]  (.drawImage g image 0 0 nil))))
   13.68 +
   13.69 +(defn screenshot "grab screenshot" [] 
   13.70 +  
   13.71 +  (ImageIO/write
   13.72 +   (.createScreenCapture (Robot.) (Rectangle. (.getScreenSize (Toolkit/getDefaultToolkit))))
   13.73 +   "JPG"
   13.74 +   (File. "/home/r/Desktop/screenie.jpg")))
   13.75 +
   13.76 +(defn- readerRecurse
   13.77 +  "calls .readPacket until there's nothing left to do"
   13.78 +  [reader]
   13.79 +  (if (not (nil? (.readPacket reader))) ; here .readPacket actually does the processing as a side-effect.
   13.80 +    nil                                   ; it returns null when it has MORE to process, and signals an error when done... 
   13.81 +    (recur reader)))
   13.82 +
   13.83 +(defmacro times
   13.84 +  "perform multiple timed tests on a form"
   13.85 +  [n form]
   13.86 +  `(dotimes [_# ~n] (time ~form)))
   13.87 +  
   13.88 +(defmacro me-1
   13.89 +  "does macroexpand-1 without having to quote the form"
   13.90 +  [form]
   13.91 +  (list 'macroexpand-1 (list 'quote form)))
   13.92 +
   13.93 +;Major Functions
   13.94 +
   13.95 +(defmulti  display "Creates a JFrame and displays a buffered image"  class)
   13.96 +
   13.97 +(defmethod display 
   13.98 +  BufferedImage  [image] 
   13.99 +  (let [panel (makePanel image)
  13.100 +	frame (JFrame. "Oh Yeah!")]
  13.101 +    (.add frame panel) 
  13.102 +    (.pack frame) 
  13.103 +    (.setVisible frame true ) 
  13.104 +    (.setSize frame(.getWidth image) (.getHeight image))))
  13.105 +
  13.106 +(defmethod display
  13.107 +  cxcore$IplImage [image]
  13.108 +  ( display (.getBufferedImage image)))
  13.109 +  
  13.110 +(defmethod display
  13.111 +  String [image]
  13.112 +  (display (highgui/cvLoadImage image highgui/CV_LOAD_IMAGE_COLOR)))
  13.113 +
  13.114 +(defmethod display
  13.115 +  LazySeq [s]
  13.116 +  (display (first s)))
  13.117 +
  13.118 +
  13.119 +(defn convert
  13.120 +  "takes video and converts it to a new type of video"
  13.121 +  [videoInput videoOutput]
  13.122 +  (let [reader (ToolFactory/makeReader videoInput)]
  13.123 +    (doto reader
  13.124 +      (.addListener (ToolFactory/makeWriter videoOutput reader))
  13.125 +      (.addListener (ToolFactory/makeDebugListener (into-array [IMediaDebugListener$Event/META_DATA]))))
  13.126 +    (readerRecurse reader)))
  13.127 +
  13.128 +
  13.129 +
  13.130 +(defn video-frame
  13.131 +  ":("
  13.132 +  [video frame]
  13.133 +  (lazy-seq
  13.134 +   (try 
  13.135 +    (let [capture (highgui/cvCreateFileCapture video)]
  13.136 +      (highgui/cvSetCaptureProperty capture highgui/CV_CAP_PROP_POS_FRAMES frame)
  13.137 +      (println (str "Wanted frame <" frame "> but went to keyFrame " (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_POS_FRAMES)))
  13.138 +      (let [out (highgui/cvQueryFrame capture)
  13.139 +	    image (.clone  out)]
  13.140 +	(highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture))
  13.141 +	[image]))
  13.142 +    (catch java.lang.NullPointerException _ nil))))
  13.143 +
  13.144 +
  13.145 +  
  13.146 +
  13.147 +(defn save-frame
  13.148 +  "takes an opencv image and saves it to disk"
  13.149 +  [frame filename]
  13.150 +  (highgui/cvSaveImage filename frame))
  13.151 +
  13.152 +
  13.153 +(defn video-len
  13.154 +  "finds out the real length of a video in log time."
  13.155 +  [video]
  13.156 +  (letfn
  13.157 +      [
  13.158 +       (accept [interval] (= 0 (interval-width interval)))
  13.159 +       (update [interval]
  13.160 +	       (let [[a b] interval]
  13.161 +		 (if (> (interval-width interval) 2)
  13.162 +		   (let [
  13.163 +			 middle (midpoint interval)
  13.164 +			 frame (first (video-frame video middle))
  13.165 +			 ]
  13.166 +		     (if (nil? frame) [a middle] [middle b]))
  13.167 +		   [a a])))
  13.168 +       ]
  13.169 +       
  13.170 +   (first (converge [-inf inf] update accept))))
  13.171 +(def video-len (memoize video-len))
  13.172 +
  13.173 +
  13.174 +
  13.175 +(defn getData
  13.176 +  "returns a bunch of stuff about a video"
  13.177 +  [video]
  13.178 +  (let
  13.179 +      [capture (highgui/cvCreateFileCapture video)
  13.180 +       info {:frames      (video-len video)
  13.181 +	     :width       (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FRAME_WIDTH)
  13.182 +	     :height      (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FRAME_HEIGHT)
  13.183 +	     :fps         (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FPS)
  13.184 +	     :codec       (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FOURCC)}]
  13.185 +      
  13.186 +    (closeCapture capture)
  13.187 +    info))
  13.188 +(def getData (memoize getData))
  13.189 +  
  13.190 +
  13.191 +(defn sajitify-linear
  13.192 +  "oh yeah!"
  13.193 +  [video string]
  13.194 +  (let [ capture (highgui/cvCreateFileCapture video)
  13.195 +	frames (:frames (getData video))]
  13.196 +       (dotimes [n frames]
  13.197 +	 (highgui/cvSaveImage (str string  (format "%06d" n) ".jpg") (highgui/cvQueryFrame capture)))
  13.198 +       (highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture))))
  13.199 +
  13.200 +(defn getFrame
  13.201 +  "gets the frame of a video at the specified time in seconds.
  13.202 +  this works with the simplest interpolation --- just piecewise steps"
  13.203 +  [video time]
  13.204 +  (lazy-seq
  13.205 +  [time  (video-frame video (int (* time (:fps (getData video)))))]))
  13.206 +
  13.207 +(defn video-seq-times
  13.208 +  "it's the new and improved version of videoSeq, now using OpenCv.
  13.209 +  we expect a sequence of times in seconds"
  13.210 +  [times video]
  13.211 +  (map #(getFrame video %) times))
  13.212 +
  13.213 +(defn video-seq
  13.214 +  "get's ALL the frames of a video as a lazy sequence of (IplImages)"
  13.215 +  [video] 
  13.216 +  (take (:frames (getData video))   (map #(video-frame video %) (iterate inc 0))))
  13.217 +
  13.218 +(defn trans-Writer
  13.219 +  "uses data about the video to make a writer"
  13.220 +  [video fileTarget]
  13.221 +  (let [data (getData video)]
  13.222 +  (highgui/cvCreateVideoWriter fileTarget (highgui/CV_FOURCC "F" "L" "V" "1") (:fps data) (cxcore/cvSize (:width data) (:height data)) 1)))
  13.223 +
  13.224 +(def naturals (iterate inc 0))
  13.225 +
  13.226 +(defn sajitify-seq
  13.227 +  [video string]
  13.228 +  (dorun (map #(highgui/cvSaveImage (str string  (format "%06d" %2) ".jpg") (first %1)) (video-seq video) naturals)))
  13.229 +
  13.230 +
  13.231 +
  13.232 +
  13.233 +
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/src/clojureDemo/VideoTransforms.clj	Fri Aug 20 00:32:44 2010 -0400
    14.3 @@ -0,0 +1,194 @@
    14.4 +(ns clojureDemo.VideoTransforms)
    14.5 +  
    14.6 +(import '(java.awt Rectangle Robot Toolkit) )
    14.7 +(import '(java.awt.image BufferedImage) )
    14.8 +(import '(java.awt Graphics2D Panel))
    14.9 +(import '(java.io File) )
   14.10 +(import '(javax.imageio ImageIO) )
   14.11 +(import '(javax.swing JFrame))
   14.12 +(import '(org.apache.commons.io FileUtils))
   14.13 +(import clojure.lang.LazySeq)
   14.14 +(import '(name.audet.samuel.javacv.jna highgui cv cxcore))
   14.15 +(import '(name.audet.samuel.javacv CanvasFrame))
   14.16 +(import '(name.audet.samuel.javacv.jna cxcore$IplImage))
   14.17 +(import '(name.audet.samuel.javacv.jna highgui$CvCapture$PointerByReference))
   14.18 +(import '(name.audet.samuel.javacv.jna highgui$CvVideoWriter$PointerByReference))
   14.19 +(import '(name.audet.samuel.javacv.jna cxcore$IplImage$PointerByReference))
   14.20 +(import '(name.audet.samuel.javacv.jna cxcore$IplImage))
   14.21 +(import '(name.audet.samuel.javacv JavaCvErrorCallback))
   14.22 +
   14.23 +(.redirectError (JavaCvErrorCallback.));this enables the c errors to travel up to the JVM
   14.24 +                                       ;where they can be handled.
   14.25 +
   14.26 +
   14.27 +(use '[clojureDemo.VisionCore :only (video-seq cache video-data close-writer)])
   14.28 +
   14.29 + 
   14.30 +(use 'clojure.contrib.repl-utils)
   14.31 +
   14.32 +(def -inf Double/NEGATIVE_INFINITY)
   14.33 +(def inf  Double/POSITIVE_INFINITY)
   14.34 +
   14.35 +
   14.36 +(def lian (File. "/home/r/Desktop/source-videos/lian1.mpeg"))
   14.37 +(def look (File. "/home/r/Desktop/source-videos/dramatic_look.flv"))
   14.38 +(def getto(File. "/home/r/Desktop/source-videos/Ghetto.flv"))
   14.39 +(def human0(File. "/home/r/Desktop/source-videos/vsr1/human0.avi"))
   14.40 +
   14.41 +(def base (File. "/home/r/Desktop/source-videos/"))
   14.42 +
   14.43 +(def app0 (File. base "approach0v2.avi"))
   14.44 +(def app1 (File. base "approach1v3.avi"))
   14.45 +(def app2 (File. base "approach0v3.avi"))
   14.46 +(def app3 (File. base "approach2v2.avi"))
   14.47 +(def app4 (File. base "approach1v2.avi")) 
   14.48 +(def app5 (File. base "approach2v3.avi"))
   14.49 +  
   14.50 +(def bounce0 (File. base "bounce0v2.avi"))  
   14.51 +(def bounce1 (File. base "bounce1v3.avi")) 
   14.52 +(def bounce2 (File. base "bounce3v2.avi"))
   14.53 +(def bounce3 (File. base "bounce0v3.avi"))  
   14.54 +(def bounce4 (File. base "bounce2v2.avi"))
   14.55 +(def bounce5 (File. base "bounce1v2.avi"))  
   14.56 +(def bounce6 (File. base "bounce2v3.avi"))
   14.57 +
   14.58 +(def collide0 (File. base "collide0v3.avi"))  
   14.59 +(def collide1 (File. base "collide2v3.avi")) 
   14.60 +(def collide2 (File. base "collide1v2.avi"))
   14.61 +(def collide3 (File. base "collide0v2.avi"))  
   14.62 +(def collide4 (File. base "collide1v3.avi")) 
   14.63 +  
   14.64 +(def give0 (File. base "give0v3.avi"))  
   14.65 +(def give1 (File. base "give2v3.avi")) 
   14.66 +(def give2 (File. base "give1v2.avi")) 
   14.67 +(def give3 (File. base "give0v2.avi"))        
   14.68 +(def give4 (File. base "give1v3.avi"))
   14.69 +
   14.70 +
   14.71 +(def target (File. "/home/r/Desktop/output-vision/"))
   14.72 +(def default(File. target "default.avi"))
   14.73 +(defn- makePanel [image] (proxy [Panel] [] (paint [g]  (.drawImage g image 0 0 nil))))
   14.74 +
   14.75 +(defmulti  display "Creates a JFrame and displays a buffered image"  class)
   14.76 +
   14.77 +(defmethod display 
   14.78 +  BufferedImage  [image] 
   14.79 +  (let [panel (makePanel image)
   14.80 +	frame (JFrame. "Oh Yeah!")]
   14.81 +    (.add frame panel) 
   14.82 +    (.pack frame) 
   14.83 +    (.setVisible frame true ) 
   14.84 +    (.setSize frame(.getWidth image) (.getHeight image))))
   14.85 +
   14.86 +(defmethod display
   14.87 +  cxcore$IplImage [image]
   14.88 +  ( display (.getBufferedImage image)))
   14.89 +  
   14.90 +(defmethod display
   14.91 +  String [image]
   14.92 +  (display (highgui/cvLoadImage image highgui/CV_LOAD_IMAGE_COLOR)))
   14.93 +
   14.94 +(defmethod display
   14.95 +  LazySeq [s]
   14.96 +  (display (first s)))
   14.97 +
   14.98 +
   14.99 +(defn video-writer
  14.100 +  "uses data about the video to make a writer"
  14.101 +  [data fileTarget]
  14.102 +  (highgui/cvCreateVideoWriter 
  14.103 +   (str fileTarget)
  14.104 +   
  14.105 +   ;(highgui/CV_FOURCC \P,\I,\M,\1) ;= MPEG-1 codec  (112913.386195 msecs) (104 MB)
  14.106 +   ;(highgui/CV_FOURCC \M,\J,\P,\G) ;= motion-jpeg codec (crashed)
  14.107 +   ;(highgui/CV_FOURCC \M,\P,\4,\2) ;= MPEG-4.2 codec (107184.186774 msecs) (82 MB)
  14.108 +   ;(highgui/CV_FOURCC \D,\I,\V,\3) ;= MPEG-4.3 codec (118308.933328 msecs)  (83 MB)
  14.109 +   ;;(highgui/CV_FOURCC \D,\I,\V,\X) ;= MPEG-4 codec    (99037.738131 msecs)  (85 MB)
  14.110 +   (highgui/CV_FOURCC \H,\D,\Y,\C)
  14.111 +   ;(highgui/CV_FOURCC \U,\2,\6,\3) ;= H263 codec     (101141.993551 msecs) (89 MB)
  14.112 +   ;(highgui/CV_FOURCC \I,\2,\6,\3) ;= H263I codec      (crashed)
  14.113 +   ;(highgui/CV_FOURCC \F,\L,\V,\1) ;= FLV1 codec     (104307.567802 msecs) (93 MB)
  14.114 +   ;(:codec data)                    ;= whatever the movie originally had.  (98278.694169 msecs) (1.9 GB)  
  14.115 +
  14.116 +   (:fps data) (cxcore/cvSize (:width data) (:height data)) 
  14.117 +   1; 1 here means that we're writing in color.
  14.118 +    ; you cannot change it to 0 to write in 
  14.119 +    ; black and white. Everything just crashes instead.
  14.120 +    ; what a useful paramater.
  14.121 +   ))
  14.122 +
  14.123 +
  14.124 +(defn naturals []  (iterate inc 0))
  14.125 +
  14.126 +
  14.127 +(defn write-frame
  14.128 +  [writer frame]
  14.129 +  (do
  14.130 +    (highgui/cvWriteFrame writer frame)
  14.131 +    frame))
  14.132 +
  14.133 +(defn number-seq
  14.134 +  [video-seq]
  14.135 +  (map #(vector %1 %2) (naturals) video-seq))
  14.136 +
  14.137 +(defn save-seq 
  14.138 +  [writer video-seq]
  14.139 +  (map #(write-frame writer %) video-seq))
  14.140 +  
  14.141 +(defn create-runonce [function]
  14.142 +  (let [sentinel (Object.)
  14.143 +	result (atom sentinel)]
  14.144 +    (fn [& args]
  14.145 +      (locking sentinel
  14.146 +	(if (= @result sentinel)
  14.147 +	  (reset! result (function))
  14.148 +	  @result)))))
  14.149 +
  14.150 +(defmacro oncer 
  14.151 +  [video-seq-gen]
  14.152 +  `((create-runonce #(~@video-seq-gen))))
  14.153 +
  14.154 +(defmacro trans-save
  14.155 +"there's a small problem with trans-save --- it IS
  14.156 +truly transitive, but it does too much work....
  14.157 +sometimes it writes files twice.
  14.158 +this is functionally correct though."
  14.159 +  [target config video-seq]
  14.160 +  `(let [writer# (video-writer ~config ~target)]
  14.161 +     (do
  14.162 +       (dorun (save-seq writer# ~video-seq))
  14.163 +       (close-writer writer#)
  14.164 +       ~video-seq)))
  14.165 +
  14.166 +(defn save-video
  14.167 +  [video target]
  14.168 +  (let [writer (video-writer (video-data video) target)]
  14.169 +    (do 
  14.170 +      (dorun (map #(write-frame writer %) (video-seq video)))
  14.171 +      (close-writer writer))))
  14.172 +
  14.173 +
  14.174 +(comment (Examples of things you can try that will actually work)
  14.175 +
  14.176 +(def lazy-human (video-seq human0)) ;makes a lazy sequence of frames and returns instantly.
  14.177 +(def target1 (File. "some/path/out1.avi")) ;just creates a normal Java File object.
  14.178 +(def target2 (File. "some/other/path/out2.avi"))
  14.179 +(def human0-data (video-data human0)) ;creates a map containing the fps, width, and height of the video. 
  14.180 +
  14.181 +(trans-save target human0-data (video-seq human0))
  14.182 +;saves a copy of human0 to disk.
  14.183 +
  14.184 +(trans-save target2 human0-data (video-seq-filter (trans-save target1 human0-data (video-seq human0))))
  14.185 +;saves an unaltered copy of human0 to disk, filters the sequence of 
  14.186 +;Intel Processing Library images by video-seq-filter, and writes the 
  14.187 +;filtered result to disk.  video-seq-filter could discard every other frame,
  14.188 +;take the sequence by fives and do temporal blurring, or just turn every
  14.189 +;frame to black and white. 
  14.190 +
  14.191 +
  14.192 +(do (use :reload-all 'clojureDemo.VideoTransforms) (in-ns 'clojureDemo.VideoTransforms))
  14.193 +
  14.194 +)
  14.195 +
  14.196 + 
  14.197 +
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/src/clojureDemo/VisionCore.clj	Fri Aug 20 00:32:44 2010 -0400
    15.3 @@ -0,0 +1,229 @@
    15.4 +(ns clojureDemo.VisionCore)
    15.5 +  
    15.6 +(import '(java.awt Rectangle Robot Toolkit) )
    15.7 +(import '(java.awt.image BufferedImage) )
    15.8 +(import '(java.awt Graphics2D Panel))
    15.9 +(import '(java.io File) )
   15.10 +(import '(javax.imageio ImageIO) )
   15.11 +(import '(javax.swing JFrame))
   15.12 +(import '(org.apache.commons.io FileUtils))
   15.13 +(import clojure.lang.LazySeq)
   15.14 +(import '(name.audet.samuel.javacv.jna highgui cv cxcore))
   15.15 +(import '(name.audet.samuel.javacv CanvasFrame))
   15.16 +(import '(name.audet.samuel.javacv.jna cxcore$IplImage))
   15.17 +(import '(name.audet.samuel.javacv.jna highgui$CvCapture$PointerByReference))
   15.18 +(import '(name.audet.samuel.javacv.jna highgui$CvVideoWriter$PointerByReference))
   15.19 +(import '(name.audet.samuel.javacv.jna cxcore$IplImage$PointerByReference))
   15.20 +(import '(name.audet.samuel.javacv.jna cxcore$IplImage))
   15.21 +(import '(name.audet.samuel.javacv JavaCvErrorCallback))
   15.22 +(.redirectError (JavaCvErrorCallback.))
   15.23 +
   15.24 +(use 'clojure.contrib.repl-utils)
   15.25 +
   15.26 +(def -inf Double/NEGATIVE_INFINITY)
   15.27 +(def inf  Double/POSITIVE_INFINITY)
   15.28 +
   15.29 +
   15.30 +
   15.31 +(def lian (File. "/home/r/Desktop/source-videos/lian1.mpeg"))
   15.32 +(def look (File. "/home/r/Desktop/source-videos/dramatic_look.flv"))
   15.33 +
   15.34 +(def target (File. "/home/r/Desktop/output-vision/"))
   15.35 +
   15.36 +
   15.37 +;this is still a work in progress, I'll come back to it later when I understand 
   15.38 +;jna more thoroughly.  the important abstraction here is 
   15.39 +;video-seq, which gives a lazy sequence of Intel Image Processing library images.
   15.40 +
   15.41 +(defn naturals [] (iterate inc 0))
   15.42 +
   15.43 +(def ext "jpg") 
   15.44 +;see below for the rationale for this choice of extention.
   15.45 +
   15.46 +(def cache-location "/home/r/Desktop/vision-cache/")
   15.47 +
   15.48 +(defn close-capture
   15.49 +  [capture]
   15.50 +  (highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture)))
   15.51 +
   15.52 +(defn close-writer
   15.53 +  [writer] (highgui/cvReleaseVideoWriter (highgui$CvVideoWriter$PointerByReference. writer))) 
   15.54 +
   15.55 +(defn- cache-path
   15.56 +  [video]
   15.57 +  (File. cache-location (.getName video)))
   15.58 +
   15.59 +(defn- already-cached
   15.60 +  "this is the simplest and most retarded way to do it"
   15.61 +  [video]
   15.62 +  (.exists (cache-path video)))
   15.63 +
   15.64 +(defn- write-frame 
   15.65 +  [capture target-dir n]
   15.66 +  (let [image (highgui/cvQueryFrame capture)]
   15.67 +    (if (nil? image) false
   15.68 +	(highgui/cvSaveImage (str (File. target-dir (str n "."  ext))) image))))
   15.69 +
   15.70 +(defn- write-frame-bad
   15.71 +  [capture target-dir n]
   15.72 +  (println (str "saving frame: " n))
   15.73 +  (let [image (highgui/cvQueryFrame capture)]
   15.74 +    (if (nil? image) false
   15.75 +	( ImageIO/write (.getBufferedImage image) ext (File. target-dir (str n "."  ext))))))
   15.76 +
   15.77 +(defn- write-frames
   15.78 +  [video target-dir]
   15.79 +  (let [capture (highgui/cvCreateFileCapture (.getPath video))]
   15.80 +   (dorun 
   15.81 +    (for [n (naturals) :while (write-frame capture target-dir n) ] nil ))
   15.82 +    (highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture))))
   15.83 +
   15.84 +(defn- cache-frames
   15.85 +  [cache-location video]
   15.86 +  (time 
   15.87 +   (do
   15.88 +     (println "\"caching entire video structure... this will take a while... go get a snack or something :)\"")
   15.89 +     (FileUtils/deleteDirectory (cache-path video))
   15.90 +     (FileUtils/forceMkdir (cache-path video))
   15.91 +     (write-frames video  (cache-path video)))))
   15.92 +
   15.93 +(defn cache
   15.94 +  [video]
   15.95 +  (if (already-cached video) nil (cache-frames cache-location video)))
   15.96 + 
   15.97 +(defn video-len 
   15.98 +  [video] (cache video)
   15.99 +  (alength (.list (cache-path video))))
  15.100 +(def video-len (memoize video-len))
  15.101 + 
  15.102 +(defn video-data
  15.103 +  "since the opencv version is so absolutely unreliable..."
  15.104 +  [video]
  15.105 +  (let
  15.106 +      [capture (highgui/cvCreateFileCapture (.getPath video))
  15.107 +       info {:length      (video-len video)
  15.108 +	     :width       (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FRAME_WIDTH)
  15.109 +	     :height      (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FRAME_HEIGHT)
  15.110 +	     :fps         (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FPS)
  15.111 +	     :codec       (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FOURCC)}]
  15.112 +    (close-capture capture)
  15.113 +    info))
  15.114 +(def video-data (memoize video-data))
  15.115 +
  15.116 +(defn- video-frame
  15.117 +  [video n] 
  15.118 +  (cache video)
  15.119 +  (let 
  15.120 +      [c++-managed  (highgui/cvLoadImage (str (File. (cache-path video) (str n "."  ext))) highgui/CV_LOAD_IMAGE_COLOR)
  15.121 +       jvm-managed (.clone c++-managed)] 
  15.122 +	 ;this bit with the cloning is so I can deal with Garbage Collection once and for all.
  15.123 +	 ;the cpp-managed image must be manually Garbage Collected, but it's clone is managed by 
  15.124 +         ;the JVM's Garbage Collector.  By getting rid of the c++ part right here and now, no 
  15.125 +         ;other function has to worry about manual garbage collection ever again.
  15.126 +         ;Unfortunately, this doesn't seem to work for certain types of files. It's not file-size
  15.127 +         ;which is the issue, but something involving the image header.
  15.128 +    (cxcore/cvReleaseImage (.pointerByReference c++-managed))
  15.129 +    jvm-managed
  15.130 +))
  15.131 +  
  15.132 +
  15.133 +(defn- video-frame-buffered
  15.134 +  "takes one frame from a video in constant time"
  15.135 +  [video n]
  15.136 +  (cache video)
  15.137 +  (ImageIO/read (File. (cache-path video) (str n "."  ext))))
  15.138 +
  15.139 +
  15.140 +(defn- dumb-write 
  15.141 +  [video n writer]
  15.142 +  (let 
  15.143 +      [c++-managed  (highgui/cvLoadImage (str (File. (cache-path video) (str n ext))) highgui/CV_LOAD_IMAGE_COLOR)]
  15.144 +    (highgui/cvWriteFrame writer  c++-managed)
  15.145 +    (cxcore/cvReleaseImage (cxcore$IplImage$PointerByReference. c++-managed))))
  15.146 +
  15.147 +(defn video-seq
  15.148 +  "makes a lazy sequence of IPL images"
  15.149 +  ;additionally, I want to pass metadata around with the sequence.
  15.150 +  [video] (cache video)
  15.151 +  (map #(video-frame video %) (range (video-len video))))
  15.152 +
  15.153 +
  15.154 +
  15.155 +
  15.156 +
  15.157 +
  15.158 +(comment
  15.159 +
  15.160 +; I initially decided to use .sr because it loads the fastest out of all the 
  15.161 +; formats opencv supports, under a simple benchmark of reading/writing
  15.162 +; a blank file of each  type 100 times.
  15.163 +
  15.164 +  ;I just kept changing the file extention at the REPL to generate these times.     
  15.165 +  (def file "test.tiff")
  15.166 +  (do 
  15.167 +    (time (dotimes [_ 100] (highgui/cvSaveImage (str cache-location file) ipl)))
  15.168 +    (time (dotimes [_ 100]  (highgui/cvLoadImage (str cache-location file)))))
  15.169 +
  15.170 +  ;      Write              Read
  15.171 +  (jpg  4404.000955 msecs 3397.8564   msecs)
  15.172 +  (jpeg 4376.138853 msecs 3482.990118 msecs)
  15.173 +  (jpeg 4253.721501 msecs 3414.004122 msecs)
  15.174 +  (bmp  3488.281695 msecs  786.883035 msecs)
  15.175 +  (dib  3589.010247 msecs  685.681985 msecs)
  15.176 +  (jpe  4288.541679 msecs 3359.819425 msecs)
  15.177 +  (png 10127.648557 msecs 3786.184994 msecs)
  15.178 +  (pbm  3880.794141 msecs  917.737667 msecs)
  15.179 +  (pgm  3879.710445 msecs  894.78237  msecs)
  15.180 +  (ppm  3938.319148 msecs 1014.412766 msecs)
  15.181 +  (sr   3510.893891 msecs  676.502596 msecs)
  15.182 +  (dib  3434.654784 msecs  737.495844 msecs)
  15.183 +  (bmp  3354.956726 msecs  783.353025 msecs)
  15.184 +  (ras  3351.400751 msecs  722.548007 msecs)
  15.185 +  (tiff 3657.893326 msecs 1361.576798 msecs)
  15.186 +  (tif  3594.753736 msecs 1254.568533 msecs)
  15.187 +
  15.188 +;Ah, but now it's time for some more tests.
  15.189 +;I started using
  15.190 +(def ext ".sr")
  15.191 +;, and an empty cache, and ran
  15.192 +(cache lian)
  15.193 +"caching entire video structure... this will take a while... go get a snack or something :)"
  15.194 +"Elapsed time: 56486.816728 msecs"
  15.195 +(time (dorun (video-seq lian)))
  15.196 +"Elapsed time: 120515.66221 msecs"
  15.197 +(time (dorun (video-seq lian)))
  15.198 +"Elapsed time: 122867.82989 msecs" ;good agreement with times
  15.199 +
  15.200 +;*erased vision cache with*
  15.201 +;*rm -rf ~/Desktop/vision-cache *
  15.202 +(def ext ".bmp")
  15.203 +(cache lian)
  15.204 +"Elapsed time: 59613.624691 msecs"
  15.205 +(time (dorun (video-seq lian)))
  15.206 +"Elapsed time: 123850.390784 msecs"
  15.207 +
  15.208 +;same process except with
  15.209 +(def ext ".jpg")
  15.210 +(cache lian)
  15.211 +"Elapsed time: 139964.031921 msecs"
  15.212 +(time (dorun (video-seq lian)))
  15.213 +"Elapsed time: 127740.50204 msecs"
  15.214 +
  15.215 +;I find this quite shocking --- the jpg's do take longer to cache,
  15.216 +;but the processing time is almost the same!
  15.217 +
  15.218 +;since lian is 434 MB as a bunch of jpg files, and 3.7 GB as .sr files,
  15.219 +;I'll go with the jpgs.
  15.220 +
  15.221 +
  15.222 +;; writing files
  15.223 +
  15.224 +"JPG"
  15.225 +(time (write-video sarah (File. "/home/r/Desktop/clojure2.avi")))
  15.226 +"Elapsed time: 371541.024455 msecs"
  15.227 +
  15.228 +"BMP"
  15.229 +(time (write-video sarah (File. "/home/r/Desktop/clojure3.avi")))
  15.230 +"Elapsed time: 382568.502361 msecs"
  15.231 +
  15.232 +)
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/clojureDemo/VisionReader.clj	Fri Aug 20 00:32:44 2010 -0400
    16.3 @@ -0,0 +1,31 @@
    16.4 +(ns clojureDemo.VisionReader
    16.5 +  (:gen-class
    16.6 +   :implements [connections.WiredBox]
    16.7 +   :methods [ [process [Object] void] [setFile [Object] void] ]
    16.8 +   :post-init register))
    16.9 +
   16.10 +(import '(davidNackoul PlotUnitMatchAlgorithm StoryGraph PlotUnit))
   16.11 +(import '(bridge.reps.things Sequence Thing))
   16.12 +
   16.13 +
   16.14 +(defn -setFile
   16.15 +  [this file]
   16.16 +  (println "file is " file))
   16.17 +
   16.18 +(defn -register
   16.19 +   "equivalent to Connections.getPorts(this).addSignalProcessor(\"process\"); in Java"
   16.20 +   [this]
   16.21 +   (println "ClojureBox  (register) : Register is run 
   16.22 +    only when the object is created, as if it were in every constructor.")
   16.23 +   (. (connections.Connections/getPorts this) addSignalProcessor "process"))
   16.24 +
   16.25 +(defn -process [ _ _ ]
   16.26 +  (println "ClojureBox (process) :  This is a LISP function, 
   16.27 +   being called through Java, through the wiredBox metaphor."))
   16.28 +
   16.29 +(defn -getName
   16.30 +  "the [_] means that  the function gets an explicit 'this'
   16.31 +    argument, just like python. In this case we don't care about it."
   16.32 +  [_]  "VisionReader")
   16.33 +
   16.34 + 
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/clojureDemo/WiredDemo.clj	Fri Aug 20 00:32:44 2010 -0400
    17.3 @@ -0,0 +1,40 @@
    17.4 +(ns clojureDemo.WiredDemo
    17.5 +(		
    17.6 + :gen-class
    17.7 + :implements [connections.WiredBox]
    17.8 + :methods [ [process [Object] void]]
    17.9 + :post-init register
   17.10 +)
   17.11 +)
   17.12 +   
   17.13 +
   17.14 +(defn -register [this]
   17.15 +
   17.16 +; translate:
   17.17 +; Connections.getPorts(this).addSignalProcessor("process");
   17.18 +; ---- to -----
   17.19 +
   17.20 +(println "ClojureBox  (register) : Register is run only when the object is created, like a constructor.")
   17.21 +
   17.22 +(. (connections.Connections/getPorts this) addSignalProcessor "process")
   17.23 +
   17.24 +
   17.25 +)
   17.26 +
   17.27 +
   17.28 +(defn -process [ _ _ ]
   17.29 +(println "ClojureBox (process) :  This is a LISP function, being called through Java, through the wiredBox metaphor.")
   17.30 +)
   17.31 +
   17.32 +
   17.33 +
   17.34 +
   17.35 +(
   17.36 +defn -getName [_]  "ClojureBox"
   17.37 +
   17.38 +; the [_] means that  the function gets an explicit "this" argument, like python,
   17.39 +; but we don't care about it.
   17.40 +
   17.41 +)
   17.42 +
   17.43 + 
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/src/clojureDemo/Xuggle.clj	Fri Aug 20 00:32:44 2010 -0400
    18.3 @@ -0,0 +1,221 @@
    18.4 +(ns clojureDemo.Xuggle)
    18.5 +
    18.6 +(import '(ij ImagePlus IJ))
    18.7 +(import '(java.awt Rectangle Robot Toolkit) )
    18.8 +(import '(java.awt.image BufferedImage) )
    18.9 +(import '(java.awt Graphics2D Panel))
   18.10 +(import '(java.io File) )
   18.11 +(import '(javax.imageio ImageIO) )
   18.12 +(import '(com.xuggle.mediatool ToolFactory))
   18.13 +(import '(com.xuggle.mediatool IMediaDebugListener IMediaDebugListener$Event))
   18.14 +(import '(com.xuggle.mediatool MediaToolAdapter MediaListenerAdapter))
   18.15 +(import '(com.xuggle.xuggler IContainer IContainer$Type IPacket))
   18.16 +(import '(javax.swing JFrame))
   18.17 +(import '(com.xuggle.mediatool IMediaWriter))
   18.18 +(import '(org.apache.commons.io FileUtils))
   18.19 +(import '(javax.imageio.stream FileImageOutputStream))
   18.20 +(import '(javax.imageio ImageWriteParam IIOImage))
   18.21 +(import '(com.xuggle.xuggler IRational))
   18.22 +(import '(java.util.concurrent TimeUnit))
   18.23 +(import '(com.xuggle.xuggler ICodec))
   18.24 +
   18.25 +(use  'clojureDemo.Defines)
   18.26 +;(use '[clojureDemo.OpenCv :only (video-data)])
   18.27 +
   18.28 +
   18.29 +
   18.30 +(import '(java.io File))
   18.31 +(import '(org.apache.commons.io FileUtils))
   18.32 +(import '(javax.imageio ImageIO) )
   18.33 +
   18.34 +(import '(ij.plugin PlugIn))
   18.35 +(import '(ij ImagePlus IJ))
   18.36 +
   18.37 +
   18.38 +(use 'clojure.contrib.repl-utils)
   18.39 +(use ['clojureDemo.Defines 
   18.40 +      :only '(
   18.41 +	     lian look getto human0 blow base app0 app1 app2 app3 app4 app5 
   18.42 +		  bounce0 bounce1 bounce2 bounce3 bounce4 bounce5 bounce6
   18.43 +		  collide0 collide1 collide2 collide3 collide4  
   18.44 +		  give0 give1 give2 give3 give4 target default)])
   18.45 +
   18.46 +
   18.47 +;(def hamster (ImagePlus. "lklk" (first (video-seq look))))
   18.48 +
   18.49 +
   18.50 +
   18.51 +
   18.52 +
   18.53 +(defn- makePanel [image] (proxy [Panel] [] (paint [g]  (.drawImage g image 0 0 nil))))
   18.54 +
   18.55 +
   18.56 +(defmulti  display "Creates a JFrame and displays a buffered image"  class)
   18.57 +
   18.58 +(defmethod display 
   18.59 +  BufferedImage  [image] 
   18.60 +  (let [panel (makePanel image)
   18.61 +	frame (JFrame. "Oh Yeah!")]
   18.62 +    (.add frame panel) 
   18.63 +    (.pack frame) 
   18.64 +    (.setVisible frame true ) 
   18.65 +    (.setSize frame(.getWidth image) (.getHeight image))))
   18.66 + 
   18.67 +(defmethod display
   18.68 +  ImagePlus [image]
   18.69 +  (display (.getBufferedImage image)))
   18.70 +
   18.71 +
   18.72 +
   18.73 +
   18.74 +(defn flash
   18.75 +     [image]
   18.76 +     
   18.77 +     (.start (Thread. (fn [] 
   18.78 +			(do 
   18.79 +			  (.show image)
   18.80 +			  (.updateAndRepaintWindow image)
   18.81 +			  (Thread/sleep 4000)
   18.82 +			  (.hide image))))))
   18.83 +
   18.84 +
   18.85 +(defn readerRecurse
   18.86 +  "calls .readPacket until there's nothing left to do"
   18.87 +  [reader]
   18.88 +  (if (not (nil? (.readPacket reader))) ; here .readPacket actually does the processing as a side-effect.
   18.89 +    nil                                   ; it returns null when it has MORE to process, and signals an error when done... 
   18.90 +    (recur reader)))
   18.91 +
   18.92 +
   18.93 +(def *cache-directory* (File. "/home/r/Desktop/vision-cache"))
   18.94 +(def *ext* "jpg")
   18.95 +
   18.96 +
   18.97 +
   18.98 +
   18.99 +(defn writeJpg
  18.100 +  "WTF is this shit?!"
  18.101 +  [image target quality]
  18.102 +  (let [jpgWriter (.next (ImageIO/getImageWritersByFormatName *ext*))]
  18.103 +    (doto (.getDefaultWriteParam jpgWriter) 
  18.104 +      (.setCompressionMode ImageWriteParam/MODE_EXPLICIT)
  18.105 +      (.setCompressionQuality quality))
  18.106 +    (doto jpgWriter
  18.107 +      (.setOutput (FileImageOutputStream. target))
  18.108 +      (.write (IIOImage. image nil nil))
  18.109 +      (.dispose))))
  18.110 +    
  18.111 +
  18.112 +
  18.113 +(defn cache-path
  18.114 +  [video]
  18.115 +  (File. *cache-directory* (.getName video)))
  18.116 +
  18.117 +(defn video-frame-path
  18.118 +     [video n]
  18.119 +     (File. (cache-path video)  (str n "."  *ext*)))
  18.120 +
  18.121 +
  18.122 +(defn already-cached
  18.123 +  "this is the simplest and most retarded way to do it"
  18.124 +  [video]
  18.125 +  (.exists (cache-path video)))
  18.126 +
  18.127 +
  18.128 + 
  18.129 + 
  18.130 +
  18.131 +
  18.132 +(defn make-incrementer [start increment] (let [a (ref (- start increment))] (fn [] (dosync (ref-set a (+ @a increment))))))
  18.133 +
  18.134 +(defn make-frame-writer
  18.135 +  [video]
  18.136 +  (let [incrementer (make-incrementer 0 1)]
  18.137 +  (proxy [MediaListenerAdapter] [] 
  18.138 +    
  18.139 +    (onVideoPicture
  18.140 +     [event]
  18.141 +     ;(println (.getImage event))
  18.142 +     ;(println (File. (cache-path video) (str (incrementer) "." *ext* ) ))
  18.143 +     
  18.144 +     (let [target  (File. (cache-path video) (str (incrementer) "." *ext* ))]
  18.145 +       (if (= *ext* "jpg")
  18.146 +	 (writeJpg (.getImage event)  target  1)
  18.147 +	 (ImageIO/write (.getImage event) *ext* target )))))))
  18.148 +    
  18.149 +
  18.150 +
  18.151 +(defn cache 
  18.152 +  "caching of frames without opencv"
  18.153 +  [video]
  18.154 +  
  18.155 +  (if (already-cached video)
  18.156 +    nil 
  18.157 +    (time
  18.158 +    (let [reader (ToolFactory/makeReader (str video))]
  18.159 +      (println "slow cache!")
  18.160 +      (FileUtils/forceMkdir (cache-path video))
  18.161 +      (doto reader
  18.162 +	(.setBufferedImageTypeToGenerate BufferedImage/TYPE_3BYTE_BGR)
  18.163 +	(.addListener  (make-frame-writer video))
  18.164 +	(.addListener (ToolFactory/makeDebugListener (into-array [IMediaDebugListener$Event/META_DATA]))))
  18.165 +      (readerRecurse reader)))))
  18.166 +
  18.167 +
  18.168 +(defn video-data 
  18.169 +  "get video data without opencv"
  18.170 +  [video] (cache video)
  18.171 +
  18.172 +  
  18.173 +  {:length (- (count (file-seq (cache-path video))) 1)
  18.174 +   :width  (.getWidth (ImagePlus. (str (video-frame-path video 0))))
  18.175 +   :height (.getHeight (ImagePlus. (str (video-frame-path video 0))))
  18.176 +   :fps 30}) ; yeah --- I'll figure this out later.
  18.177 + (def video-data (memoize video-data))
  18.178 +
  18.179 +
  18.180 +
  18.181 +(defn convert
  18.182 +  "takes video and converts it to a new type of video"
  18.183 +  [videoInput videoOutput]
  18.184 +  (let [reader (ToolFactory/makeReader (str videoInput))]
  18.185 +    (doto reader
  18.186 +      (.addListener (ToolFactory/makeWriter (str videoOutput) reader))
  18.187 +      (.addListener (ToolFactory/makeDebugListener (into-array [IMediaDebugListener$Event/META_DATA]))))
  18.188 +    (readerRecurse reader)))
  18.189 +
  18.190 +
  18.191 +(import '(com.xuggle.xuggler.video ConverterFactory))
  18.192 +
  18.193 +
  18.194 +(defn trans-save
  18.195 +  "this is a transitive way to save a stream to an avi file.
  18.196 +   It uses meta data to determine what fps to use to encode."
  18.197 +  [destination video-seq]
  18.198 +  (let [data (meta video-seq)
  18.199 +	writer (ToolFactory/makeWriter (str destination))
  18.200 +	incrementer (make-incrementer 0 (/ 1 30))]
  18.201 +    (.addVideoStream writer 0 0 (ICodec/findEncodingCodecByName "mpeg4") 
  18.202 +		     (IRational/make (double (:fps data))) 
  18.203 +		     (int (:width data)) (int (:height data)))
  18.204 +    (dorun (map  #(.encodeVideo writer 0 
  18.205 +			 (ConverterFactory/convertToType (.getBufferedImage %) BufferedImage/TYPE_3BYTE_BGR) 
  18.206 +			(long (* 1000000000 (incrementer)))  TimeUnit/NANOSECONDS)  video-seq))
  18.207 +	(.close writer))
  18.208 +  video-seq)
  18.209 +
  18.210 +
  18.211 +(defn video-seq 
  18.212 +  "let's use ImagePlus stuff!"
  18.213 +  ([video] (cache video) 
  18.214 +    (with-meta (map #(ImagePlus. (str (video-frame-path video %))) (range (:length (video-data video))) ) (video-data video))))
  18.215 +
  18.216 +
  18.217 +
  18.218 +
  18.219 +
  18.220 +
  18.221 +(comment 
  18.222 +  (do (use :reload-all 'clojureDemo.Xuggle) (in-ns 'clojureDemo.Xuggle))
  18.223 +)
  18.224 + 
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/src/clojureDemo/appeture.clj	Fri Aug 20 00:32:44 2010 -0400
    19.3 @@ -0,0 +1,103 @@
    19.4 +(ns clojureDemo.appeture)
    19.5 +
    19.6 +(use 'clojure.contrib.repl-utils)
    19.7 +(use 'clojure.contrib.accumulators)
    19.8 +
    19.9 +"right now this only will work on odd square arrays"
   19.10 +
   19.11 +(def rrr {[0 0] 20 , [1 0] 20, [2 0] 20
   19.12 +	  [0 1]  0 , [1 1]  0, [2 1]  0
   19.13 +	  [0 2]  0 , [1 2]  0, [2 2]  0})
   19.14 +
   19.15 +(def rrrr {[0 0] 20 , [1 0] 20, [2 0] 20 , [3 0] 20, [4 0] 20,
   19.16 +	   [0 1] 20 , [1 1] 20, [2 1] 20 , [3 1] 20, [4 1] 20,
   19.17 +	   [0 2]  0 , [1 2]  0, [2 2]  0 , [3 2] 0,  [4 2] 0,
   19.18 +	   [0 3]  0 , [1 3]  0, [2 3]  0 , [3 3] 0,  [4 3] 0,
   19.19 +	   [0 4]  0 , [1 4]  0, [2 4]  0 , [3 4] 0,  [4 4] 0,})
   19.20 +
   19.21 +(defn vector-mul
   19.22 +  [mul vect]
   19.23 +  (apply vector (map #(* mul %) vect)) )
   19.24 +
   19.25 +(defn vector-sum
   19.26 +  ([] 0)
   19.27 +  ([& args] 
   19.28 +  (apply vector (reduce #(map + %1 %2) args))))
   19.29 +
   19.30 +(defn vector-sub
   19.31 +  [vector1 vector2]
   19.32 +  (vector-sum vector1 (vector-mul -1 vector2)))
   19.33 + 
   19.34 +(defn vector-dot
   19.35 +  [vector1 vector2]
   19.36 +  (reduce + (map * vector1 vector2)))
   19.37 +
   19.38 +(defn center
   19.39 +  [window]
   19.40 +  (let [coords (keys window)]
   19.41 +  (vector-mul (/ 1 (count coords)) (apply vector-sum coords))))
   19.42 +
   19.43 +(defn window-segmentate
   19.44 +  [window line]
   19.45 +  (let [center (center window)]
   19.46 +  (letfn [(path   [window] (filter (fn [point] (apply = (line center point))) (keys window)))
   19.47 +	  (top    [window] (filter (fn [point] (apply > (line center point))) (keys window)))
   19.48 +	  (bottom [window] (filter (fn [point] (apply < (line center point))) (keys window)))]
   19.49 +     {:top (top window) :bottom (bottom window) :line (path window)})))
   19.50 +
   19.51 +(defn diag1
   19.52 +  [window]
   19.53 +  (window-segmentate window (fn [center point] (list (first  (vector-sub point center)) (-(last  (vector-sub point center)))))))
   19.54 +
   19.55 +(defn diag2
   19.56 +  [window]
   19.57 +(window-segmentate window  (fn [center point] (list (first (vector-sub point center)) (last  (vector-sub point center))))))
   19.58 + 
   19.59 +(defn vert
   19.60 +  [window]
   19.61 +(window-segmentate window  (fn [center point] (list (first (vector-sub point center)) 0))))
   19.62 + 
   19.63 +(defn horiz
   19.64 +  [window]
   19.65 +(window-segmentate window  (fn [center point] (list 0 (last (vector-sub point center))))))
   19.66 +
   19.67 +
   19.68 + 
   19.69 +
   19.70 + 
   19.71 +
   19.72 +(defn lines
   19.73 +  [window]    
   19.74 +    (let [lines (list (vert window) (horiz window) (diag1 window) (diag2 window))]
   19.75 +      lines))
   19.76 +;This is the wrong model.  Higher level processors should set these paramaters, and 
   19.77 +; juggle them around if they aren't getting anything they understand.
   19.78 +
   19.79 +
   19.80 +
   19.81 +(defn stats-base
   19.82 +  [sections window sel-fun]
   19.83 + (let [stats-top    (add-items empty-mean-variance (map window (:top sections)))
   19.84 +	stats-bottom (add-items empty-mean-variance (map window (:bottom sections)))]
   19.85 +   (let [ var1 (:variance stats-top) mean1 (:mean stats-top) var2 (:variance stats-bottom) mean2 (:mean stats-bottom)]
   19.86 +     (sel-fun var1 mean1 var2 mean2))))
   19.87 +
   19.88 +(defn window-line
   19.89 +  [window transformation detection]
   19.90 +  (let [x-window (transformation window)]
   19.91 +    (first (filter #(stats-base % x-window detection) (lines x-window)))))
   19.92 +	       
   19.93 +(defn window-stats
   19.94 +  ([window] (window-stats window identity))
   19.95 +  ([window transformation]
   19.96 +  (let [x-window (transformation window)]
   19.97 +    (map (fn [line] (stats-base line x-window #(list %1 %2 %3 %4))) (lines x-window)))))
   19.98 +
   19.99 +
  19.100 +
  19.101 +
  19.102 +(comment 
  19.103 +
  19.104 +(do (use :reload-all 'clojureDemo.appeture) (in-ns 'clojureDemo.appeture))
  19.105 +
  19.106 +)
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/clojureDemo/explore.clj	Fri Aug 20 00:32:44 2010 -0400
    20.3 @@ -0,0 +1,11 @@
    20.4 +(ns clojureDemo.explore)
    20.5 +
    20.6 +(use 'clojure.contrib.accumulators)
    20.7 +(use 'clojure.contrib.repl-utils)
    20.8 +
    20.9 +
   20.10 +(comment 
   20.11 +
   20.12 +(do (use :reload-all 'clojureDemo.explore) (in-ns 'clojureDemo.explore))
   20.13 +
   20.14 +)
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/src/clojureDemo/import_java_fns.clj	Fri Aug 20 00:32:44 2010 -0400
    21.3 @@ -0,0 +1,10 @@
    21.4 +(ns clojureDemo.import-java-fns)
    21.5 +
    21.6 +
    21.7 +
    21.8 +(defmacro single-arg-fn [package fun]
    21.9 +  (let [name (symbol (str package "/" fun))]
   21.10 +  `(defn ~fun [a#] (~name a#))))
   21.11 +
   21.12 +(defmacro java-map [package & fns]
   21.13 +  `(do ~@(map #(list 'single-arg-fn package %) fns)))
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/src/clojureDemo/librlm.clj	Fri Aug 20 00:32:44 2010 -0400
    22.3 @@ -0,0 +1,11 @@
    22.4 +(ns clojureDemo.librlm)
    22.5 +
    22.6 +  (defmethod*  - java.lang.Boolean [x] (not x))
    22.7 +
    22.8 +;  (defmethod + [java.lang.Boolean java.lang.Boolean]
    22.9 +;    [a b] (or a b))
   22.10 +  
   22.11 +;  (defmethod * [java.lang.Boolean java.lang.Boolean]
   22.12 +;    [a b] (and a b))
   22.13 +  
   22.14 +;  (defmethod / java.lang.Boolean [x] x)
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/src/clojureDemo/librlm.clj~	Fri Aug 20 00:32:44 2010 -0400
    23.3 @@ -0,0 +1,11 @@
    23.4 +(ns clojureDemo.librlm)
    23.5 +
    23.6 +;  (defmethod*  - java.lang.Boolean [x] (not x))
    23.7 +
    23.8 +;  (defmethod + [java.lang.Boolean java.lang.Boolean]
    23.9 +;    [a b] (or a b))
   23.10 +  
   23.11 +;  (defmethod * [java.lang.Boolean java.lang.Boolean]
   23.12 +;    [a b] (and a b))
   23.13 +  
   23.14 +;  (defmethod / java.lang.Boolean [x] x)
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/src/clojureDemo/project-euler.clj~	Fri Aug 20 00:32:44 2010 -0400
    24.3 @@ -0,0 +1,16 @@
    24.4 +
    24.5 +
    24.6 +(ns clojureDemo.project-euler)
    24.7 +
    24.8 +
    24.9 +(use 'clojureDemo.rlm)
   24.10 +(rlm-base-load)
   24.11 +
   24.12 +(defn range-sum 
   24.13 +"calculates the sum of a range.  Takes the exact same arguments
   24.14 + as clojure.core/range"
   24.15 +([end]
   24.16 +   (/ (* end (- end 1) ) 2)))
   24.17 +
   24.18 +
   24.19 +
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/src/clojureDemo/project_euler.clj	Fri Aug 20 00:32:44 2010 -0400
    25.3 @@ -0,0 +1,559 @@
    25.4 +
    25.5 +(ns clojureDemo.project-euler
    25.6 +
    25.7 +(:refer-clojure :exclude [+ - / * 
    25.8 +			  assoc conj dissoc empty get into seq
    25.9 +			  = < > <= >= zero?
   25.10 +			  ])
   25.11 +
   25.12 +(:use [clojure.contrib.generic
   25.13 +	 arithmetic
   25.14 +	 collection
   25.15 +	 comparison
   25.16 +	 ])
   25.17 +
   25.18 +(:use [clojure.contrib
   25.19 +	 combinatorics
   25.20 +	 repl-utils
   25.21 +	 def
   25.22 +	 duck-streams
   25.23 +	 shell-out
   25.24 +	 import-static
   25.25 +	 lazy-seqs
   25.26 +	 logging
   25.27 +	 map-utils
   25.28 +	 math
   25.29 +	 mock
   25.30 +	 monads
   25.31 +	 ns-utils
   25.32 +         seq-utils
   25.33 +         function-utils
   25.34 +       profile
   25.35 +       str-utils
   25.36 +	 ])
   25.37 +
   25.38 +(:use [clojure.contrib.pprint :exclude [write]])
   25.39 +  
   25.40 +(:use [clojure.contrib.pprint.examples
   25.41 +	 hexdump
   25.42 +	 json
   25.43 +	 multiply
   25.44 +	 props
   25.45 +	 show-doc
   25.46 +	 xml
   25.47 +	 ])
   25.48 +
   25.49 +(:import java.io.File)
   25.50 +(:import [java.util Calendar Date])
   25.51 +
   25.52 +)
   25.53 +
   25.54 +
   25.55 +
   25.56 +
   25.57 +
   25.58 +(defn range-sum 
   25.59 +  "calculates the sum of a range.  Takes the exact same arguments
   25.60 +  as clojure.core/range equilivent to (reduce + (range start end step)), but O(1)."
   25.61 +  ([end]
   25.62 +     (/ (* end (- end 1) ) 2))
   25.63 +  
   25.64 +  ([start end]
   25.65 +     (- (range-sum end) (range-sum start)))
   25.66 +
   25.67 +  ([start end step]
   25.68 +     (letfn [(zero-sum [end step] (* step (range-sum 0 (ceil (/ end step)))))]
   25.69 +     (+ (zero-sum (- end start) step) (* start (int (/ (- end start) step)))))))
   25.70 +
   25.71 +
   25.72 +
   25.73 +(defn range-sum-squares
   25.74 +  "equivalent to (reduce + (map #(expt % 2) (range start end step))), 
   25.75 +   but runs in O(1) time."
   25.76 +  ([end]
   25.77 +     (let [n (- end 1)]
   25.78 +     (- (* (expt n 3) 1/3) ;continous volume
   25.79 +	(+ (* -1/6 n) (* -1/2 (expt n 2)))))) ;discrete correction
   25.80 +
   25.81 +   ([start end]
   25.82 +     (- (range-sum-squares end) (range-sum-squares start)))
   25.83 +
   25.84 +   ([start end step]
   25.85 +      ;; (letfn [(zero-sum-squares [end step]
   25.86 +      ;; 				(* step step (range-sum-squares 0 (ceil (/ end step)))))]
   25.87 +      ;; 	(+ 
   25.88 +      ;; 	 (* 2 step (range-sum (ceil (/ (- end start) step))))
   25.89 +      ;; 	 (zero-sum end step) 
   25.90 +      ;; 	 (* start start (int (/ (- end start) step)))))))
   25.91 +))	
   25.92 +
   25.93 +
   25.94 +(defn prime-factors 
   25.95 +  "all the prime factors of the number n"
   25.96 +  [n]
   25.97 +  (filter #(= 0 (rem n %)) (for [p primes :while (<= p n)] p)))
   25.98 +
   25.99 +(defn factor? [a b] (= 0 (rem a b)))
  25.100 +
  25.101 +(defn factor-map [a b]
  25.102 +  (if (factor? a b) 
  25.103 +	{b (quot a b)}
  25.104 +	nil))
  25.105 +
  25.106 +
  25.107 +(defn divides? [numerator divisor] (= (rem numerator divisor) 0))
  25.108 +
  25.109 +
  25.110 +(def != (comp not =))
  25.111 +
  25.112 +
  25.113 +(defn decompose [number factor]
  25.114 +    (loop [n number counter 0]
  25.115 +      (if (!= (rem n factor) 0)
  25.116 +        counter
  25.117 +	(recur (/ n factor) (inc counter)))))
  25.118 +
  25.119 +	
  25.120 +
  25.121 +
  25.122 +
  25.123 +
  25.124 +
  25.125 +(defn single-factor [{num :current-num index :prime-index factors :prime-factors :as old-state}]
  25.126 +  (let [divisor (nth primes index)
  25.127 +	new-index (inc index)
  25.128 +	done? (= num 1)]
  25.129 +    (if (divides? num divisor)
  25.130 +      (let [new-num (/ num (expt divisor (decompose num divisor)))   
  25.131 +	    factors (assoc factors divisor (decompose num divisor))]
  25.132 +	[[factors done?] (assoc old-state
  25.133 +		 :current-num new-num :prime-index new-index :prime-factors factors)])
  25.134 +      
  25.135 +      [[factors done?] (assoc old-state 
  25.136 +	       :current-num num :prime-index new-index :prime-factors factors)])))
  25.137 +      
  25.138 +
  25.139 +(defn wtf "a is not used" [a] (domonad state-m [part single-factor] part))
  25.140 +
  25.141 +(defn fuck-it [] 
  25.142 +  (domonad state-m 
  25.143 +	   [[factors done?]
  25.144 +	    (state-m-until second wtf nil)]
  25.145 +	   
  25.146 +	   factors))
  25.147 +
  25.148 +(defn prime-factor-map [num]
  25.149 +  
  25.150 +  (first ((fuck-it) {:prime-factors {}
  25.151 +		     :prime-index 0
  25.152 +		     :current-num num})))
  25.153 +
  25.154 +(defn prime-factors-monad [num]
  25.155 +  (sort (keys (prime-factor-map num))))
  25.156 +
  25.157 +
  25.158 +
  25.159 +
  25.160 +
  25.161 +
  25.162 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  25.163 +;; fun with state monad
  25.164 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  25.165 +
  25.166 +
  25.167 +(defn ++ [{num :num :as world}]
  25.168 +  (let [num++ (inc num)]
  25.169 +    [num++ (assoc world :num num++)]))
  25.170 +
  25.171 +(defn huh? []
  25.172 +  (with-monad state-m 
  25.173 +    (domonad [x ++
  25.174 +	      y ++]
  25.175 +	     y)))
  25.176 +
  25.177 +
  25.178 +(comment 
  25.179 +
  25.180 +huh?
  25.181 +->
  25.182 +((let [m-bind (fn m-bind-state [mv f]
  25.183 +		(fn [s]
  25.184 +		  (let [[v ss] (mv s)]
  25.185 +		    ((f v) ss))))] 
  25.186 +       (m-bind
  25.187 +	++ (fn [x] ++))) {:num 1})
  25.188 +
  25.189 +
  25.190 +)
  25.191 +
  25.192 +
  25.193 +(defn wordify [n] (cl-format nil "~R" n))
  25.194 +    
  25.195 +(defn british-letter-count-prof [n]
  25.196 +  (prof :total
  25.197 +  (let [and? (prof :rem-test (if (and (> n 99) (!= 0 (rem n 100))) 3 0))
  25.198 +	word (prof :wordify (wordify n))
  25.199 +	word-seq (prof :sequence (seq word))
  25.200 +	word-filter (prof :filter (filter #(Character/isLetter %) word-seq))
  25.201 +	word-count (prof :count (count word-filter))
  25.202 +	answer (prof :add (+ and? word-count))]
  25.203 +    answer)))
  25.204 +
  25.205 +(defn british-letter-count-prof2 
  25.206 +"now this is faster, because it uses string manipulation.  go profiling!"
  25.207 +[n]
  25.208 +  (prof :total
  25.209 +  (let [and? (prof :rem-test (if (and (> n 99) (!= 0 (rem n 100))) 3 0))
  25.210 +	word (prof :wordify (wordify n))
  25.211 +	word-regex (prof :regex (re-gsub #"[\W-,]" "" word))
  25.212 +	
  25.213 +	word-count (prof :count (.length word-regex))
  25.214 +	answer (prof :add (+ and? word-count))]
  25.215 +    answer)))
  25.216 +
  25.217 +
  25.218 +   
  25.219 +
  25.220 +
  25.221 +
  25.222 +
  25.223 +
  25.224 +
  25.225 +
  25.226 +
  25.227 +
  25.228 +
  25.229 +
  25.230 +
  25.231 +
  25.232 +
  25.233 +
  25.234 +
  25.235 +;pseudo code for primes
  25.236 +
  25.237 +;fn prime-decomposition
  25.238 +; [n]
  25.239 +; map = {} 
  25.240 +; 
  25.241 +; for x in primes
  25.242 +;   add to map (divide teh fick out n x)
  25.243 +;   n = n / prime-factors
  25.244 +;   if n == 1 BREAK;
  25.245 +;
  25.246 +;
  25.247 +
  25.248 +
  25.249 +
  25.250 +(defn rng [seed]
  25.251 +  (let [m      259200
  25.252 +	value  (/ (float seed) (float m))
  25.253 +	next   (rem (+ 54773 (* 7141 seed)) m)]
  25.254 +    [value next]))
  25.255 +
  25.256 +
  25.257 +(defn yeah! []
  25.258 +  (let [name sequence-m 
  25.259 +	m-bind (:m-bind name) 
  25.260 +	m-result (:m-result name) 
  25.261 +	m-zero (:m-zero name) 
  25.262 +	m-plus (:m-plus name)] 
  25.263 +
  25.264 +
  25.265 +    (m-bind (range 5) (fn [a] (m-bind [2 3] (fn [b] (m-result (+ a b))))))))
  25.266 +
  25.267 +
  25.268 +(defn ohhhh!! []
  25.269 +  
  25.270 +  (let 
  25.271 +      [name state-m 
  25.272 +       m-bind (:m-bind name) 
  25.273 +       m-result (:m-result name) ]
  25.274 +    
  25.275 +    (m-bind rng (fn [x1] (m-bind rng (fn [x2] (m-result (+ x1 x2))))))))
  25.276 +
  25.277 +
  25.278 +
  25.279 +(defmulti palindrome? class)
  25.280 +  
  25.281 +(defmethod palindrome? (class "string") [a]
  25.282 +  (= (seq a) (reverse a)))
  25.283 +
  25.284 +(defmethod palindrome? (class 500) [a]
  25.285 +  (palindrome? (str a)))
  25.286 +
  25.287 +
  25.288 +
  25.289 +
  25.290 +
  25.291 +
  25.292 +
  25.293 +
  25.294 +(defn circulars 
  25.295 +  "returns a vector of all the circular permutations of a number"
  25.296 +  [n]
  25.297 +  (map #(Integer. (apply str %)) (rotations (seq (str n)))))
  25.298 +    
  25.299 +
  25.300 +(defn prime-factors
  25.301 +  [n]
  25.302 +  (for [a primes :while (<= a n) :when (= (rem n a) 0)]  a)) 
  25.303 +
  25.304 +
  25.305 +(defmethod = [nil java.lang.Integer] [ a b ]
  25.306 +  false)
  25.307 +
  25.308 +
  25.309 +
  25.310 +(def mil 1000000)
  25.311 +(def bil 1000000000)
  25.312 +
  25.313 +(defn primes-under-million [] (apply hash-set (take 78498 primes)))
  25.314 +(def primes-under-million (memoize primes-under-million))
  25.315 +
  25.316 +
  25.317 +(defn primes-under-billion [] (apply hash-set (take 664579 primes)))
  25.318 +(def primes-under-billion (memoize primes-under-billion))
  25.319 +
  25.320 +
  25.321 +
  25.322 +
  25.323 +
  25.324 +(defn prime? [n] (not (nil? (get (primes-under-billion) n))))
  25.325 +
  25.326 +
  25.327 +(defn circular-memoize 
  25.328 +  "assumes that f is a predicate that takes in a number for which, 
  25.329 +   if the predicate is true for the number, it is also true for all
  25.330 +   of the circular permutations of the number.  Memoizes the result
  25.331 +   for all circular permutations so as to avoid subsequent computation."
  25.332 +  [f]
  25.333 +   (let [mem (atom {})]
  25.334 +    (fn [n]
  25.335 +      (if-let [e (find @mem n)]
  25.336 +        (val e)
  25.337 +        (let [ret (f n)]
  25.338 +	  (dorun (for [circ (circulars n)]
  25.339 +		   (swap! mem assoc n ret)))
  25.340 +          ret)))))
  25.341 +
  25.342 +(defn circularly-prime?
  25.343 +  [n]
  25.344 +  (not (some (comp not prime?) (circulars n))))
  25.345 +
  25.346 +(def circularly-prime? (memoize circularly-prime?))
  25.347 +
  25.348 +
  25.349 +(defmethod = :default  [& args]
  25.350 +  (apply clojure.core/= args))
  25.351 +  
  25.352 +(def logins 
  25.353 +     (map str
  25.354 +	  [319 680 180 690 129 620 762 689 762 318
  25.355 +	   368 710 720 710 629 168 160 689 716 731
  25.356 +	   736 729 316 729 729 710 769 290 719 680
  25.357 +	   318 389 162 289 162 718 729 319 790 680
  25.358 +	   890 362 319 760 316 729 380 319 728 716]))
  25.359 +
  25.360 +(defn remove-multiples [n]
  25.361 +  (reduce (fn [a b] (if (= (last a) b) a (conj a b))) [] n))
  25.362 +
  25.363 +(defn insert [item n vect]
  25.364 +  (let [split (split-at n vect)]
  25.365 +    (apply vector (flatten [(first split) item (last split)]))))
  25.366 +
  25.367 +(defn expand-code [old-code [c b a]]
  25.368 +  (let [main-length (count old-code)]
  25.369 +    (for [x (range (inc main-length)) y (range (inc x)) z (range (inc y))] 
  25.370 +      (insert c z (insert b y (insert a x old-code)))))) 
  25.371 +
  25.372 +(defn domain-expand-contract [old-domain constraint]
  25.373 +  (let [new-domain 
  25.374 +	(map remove-multiples 
  25.375 +	     (remove-multiples 
  25.376 +	      (sort 
  25.377 +	       (apply concat 
  25.378 +		      (map #(expand-code % constraint) old-domain)))))
  25.379 +	min-code-length (apply min (map count new-domain)) ]
  25.380 +    (map #(apply str %) (filter #(= (count %) min-code-length) new-domain))))
  25.381 +(def domain-expand-contract (memoize domain-expand-contract))
  25.382 +
  25.383 +
  25.384 +
  25.385 +(defn lazy-fibo 
  25.386 +  ([] (concat [0 1] (lazy-fibo 0 1)))
  25.387 +  ([a b] (let [n (+ a b)] (lazy-seq (cons n (lazy-fibo b n))))))
  25.388 +
  25.389 +
  25.390 +(defn collatz-seq [n]  
  25.391 +  (lazy-seq
  25.392 +  (cond (= n 1) [1]
  25.393 +	(even? n) (lazy-seq (cons n (collatz-seq (/ n 2))))
  25.394 +	(odd? n)  (lazy-seq (cons n (collatz-seq (+ 1 (* 3 n))))))))
  25.395 +(def collatz-seq (memoize collatz-seq))
  25.396 +
  25.397 +
  25.398 +
  25.399 +(defn pythagorean-triple? [a b c]
  25.400 +  (let [[a b c] (sort [a b c])]
  25.401 +    (= (+ (* a a) (* b b) ) (* c c))))
  25.402 +
  25.403 +
  25.404 +(defn sum-squares [coll]
  25.405 +  (reduce +  (map #(* % %) coll)))
  25.406 +
  25.407 +
  25.408 +(defn british-letter-count [n]
  25.409 +  
  25.410 +  (let [and? (if (and (> n 99) (!= 0 (rem n 100))) 3 0)]
  25.411 +
  25.412 +    (+ and? (count (filter #(Character/isLetter %) (seq (wordify n)))))))
  25.413 +
  25.414 +
  25.415 +
  25.416 +(defmacro apply-macro
  25.417 +  "This is evil.  Don't ever use it.  It makes a macro behave like a
  25.418 +  function.  Seriously, how messed up is that?
  25.419 +
  25.420 +  Evaluates all args, then uses them as arguments to the macro as with
  25.421 +  apply.
  25.422 +
  25.423 +  (def things [true true false])
  25.424 +  (apply-macro and things)
  25.425 +  ;; Expands to:  (and true true false)"
  25.426 +  [macro & args]
  25.427 +  (cons macro (flatten (map eval args))))
  25.428 +
  25.429 +(defn fun1 [] (Thread/sleep 5000) 5)
  25.430 +
  25.431 +(defn fun2 [] (Thread/sleep 30000) 5)
  25.432 +
  25.433 +
  25.434 +(def naturals (iterate inc 0))
  25.435 +  
  25.436 +
  25.437 +
  25.438 +
  25.439 +(defn race []
  25.440 +  (let [result (ref nil)
  25.441 +	threads [(Thread. (fn [] (try 
  25.442 +				  (let [answer (fun1)] 
  25.443 +				    (dosync (ref-set result answer)))
  25.444 +				  (catch Exception _ nil))))
  25.445 +		 (Thread. (fn [] (try 
  25.446 +				  (let [answer (fun2)] 
  25.447 +				    (dosync (ref-set result answer))) 
  25.448 +				  (catch Exception _ nil))))]]
  25.449 +	   
  25.450 +    (dorun (map #(.start %) threads))
  25.451 +    (loop []
  25.452 +      (if (!= (deref result) nil)
  25.453 +	(do (dorun (map #(.stop %) threads))
  25.454 +	    (deref result))
  25.455 +	(recur)))))
  25.456 +
  25.457 +
  25.458 +
  25.459 +
  25.460 +
  25.461 +
  25.462 +
  25.463 +(defn make-date [year month day] (do (let [date (Calendar/getInstance)] (.set date year month day 0 0) date)))
  25.464 +
  25.465 +(def jan-1-1901 (make-date 1900 0 1))
  25.466 +
  25.467 +(defn sunday? [#^java.util.Date date] (re-matches #"^Sun.*"  (str  date)))
  25.468 +
  25.469 +(count (filter sunday? (for [a (range 1 40000) date [(.getTime (make-date 1900 0 a)) ] :while (< (.getYear date) 100)] date )))
  25.470 +
  25.471 +
  25.472 +
  25.473 +
  25.474 +(comment
  25.475 +
  25.476 +;; ----------------------------------------------------------------------
  25.477 +;; Answers
  25.478 +;; ----------------------------------------------------------------------
  25.479 +
  25.480 +; Problem 1 
  25.481 +(+ (range-sum 0 1001 3) (range-sum 0 1001 5) (* -1 (range-sum 0 1001 15)))
  25.482 +
  25.483 +; Problem 2
  25.484 +(reduce + (for [a (filter even? (fibs)) :while (<= a 4000000 )] a))
  25.485 +
  25.486 +; Problem 3
  25.487 +(apply max (prime-factors 600851475143))
  25.488 +
  25.489 +; Problem 4
  25.490 +(reduce max (for [a (range 100 1000) b (range 100 1000) :when (palindrome? (* a b))] (* a b)))
  25.491 +
  25.492 +; Problem 5
  25.493 +(reduce lcm (range 1 21))
  25.494 +
  25.495 +; Problem 6
  25.496 +(- (expt (range-sum 101) 2) (range-sum-squares 101))
  25.497 +
  25.498 +; Problem 7
  25.499 +(nth primes 10000)
  25.500 +
  25.501 +
  25.502 +; Problem 9
  25.503 +(reduce * (first (for [a (range 1 1000) b (range 1 a) c [(sqrt (sum-squares [a b]))] 
  25.504 +      :when (= (+ a b c) 1000)] [a b c])))
  25.505 +
  25.506 +; Problem 10 
  25.507 +(reduce + (for [a primes :while (< a 2000000)] a))
  25.508 +
  25.509 +
  25.510 +
  25.511 +
  25.512 +
  25.513 +; Problem 14
  25.514 +(first (reduce (fn [a b] (if (> (count a) (count b)) a b)) [] (map collatz-seq (range 1 mil))))
  25.515 +
  25.516 +
  25.517 +; Problem 16
  25.518 +(reduce + (map #(Character/getNumericValue %) (seq (str (expt 2 1000)))))
  25.519 +
  25.520 +; Problem 17
  25.521 +(reduce + (map british-letter-count (range 1 1001)))
  25.522 +
  25.523 +
  25.524 +; Problem 24
  25.525 +(nth  (lex-permutations [ 0 1 2 3 4 5 6 7 8 9]) (- mil 1))
  25.526 +
  25.527 +; Problem 33
  25.528 +(reduce * (for [num (range 1 10) 
  25.529 +      den (range 1  10) 
  25.530 +      weird (range 1 10) 
  25.531 +      top [(+ num (* 10 weird))]
  25.532 +      bottom [(+ weird (* 10 den))]
  25.533 +      :when (and (> (/ top bottom) 1) (= (/ top bottom) (/ num den)))]
  25.534 +  (/ bottom top)))
  25.535 +
  25.536 +; Problem 35
  25.537 +(count (filter circularly-prime? (primes-under-million)))
  25.538 +
  25.539 +; Problem 40 
  25.540 +(let [fff (apply str (take 1030000 naturals))] 
  25.541 +  (reduce * (map #(Character/getNumericValue (nth fff %)) 
  25.542 +		 (map (fn [x] (expt 10 x)) (range 7)) )))
  25.543 +
  25.544 +
  25.545 +
  25.546 +
  25.547 +
  25.548 +
  25.549 +; Problem 79
  25.550 +(reduce domain-expand-contract [""] logins)
  25.551 +
  25.552 +)
  25.553 +
  25.554 +
  25.555 +
  25.556 +
  25.557 +
  25.558 +
  25.559 +
  25.560 +
  25.561 +
  25.562 +
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/src/clojureDemo/project_euler.clj~	Fri Aug 20 00:32:44 2010 -0400
    26.3 @@ -0,0 +1,559 @@
    26.4 +
    26.5 +(ns clojureDemo.project-euler
    26.6 +
    26.7 +(:refer-clojure :exclude [+ - / * 
    26.8 +			  assoc conj dissoc empty get into seq
    26.9 +			  = < > <= >= zero?
   26.10 +			  ])
   26.11 +
   26.12 +(:use [clojure.contrib.generic
   26.13 +	 arithmetic
   26.14 +	 collection
   26.15 +	 comparison
   26.16 +	 ])
   26.17 +
   26.18 +(:use [clojure.contrib
   26.19 +	 combinatorics
   26.20 +	 repl-utils
   26.21 +	 def
   26.22 +	 duck-streams
   26.23 +	 shell-out
   26.24 +	 import-static
   26.25 +	 lazy-seqs
   26.26 +	 logging
   26.27 +	 map-utils
   26.28 +	 math
   26.29 +	 mock
   26.30 +	 monads
   26.31 +	 ns-utils
   26.32 +         seq-utils
   26.33 +         function-utils
   26.34 +       profile
   26.35 +       str-utils
   26.36 +	 ])
   26.37 +
   26.38 +(:use [clojure.contrib.pprint :exclude [write]])
   26.39 +  
   26.40 +(:use [clojure.contrib.pprint.examples
   26.41 +	 hexdump
   26.42 +	 json
   26.43 +	 multiply
   26.44 +	 props
   26.45 +	 show-doc
   26.46 +	 xml
   26.47 +	 ])
   26.48 +
   26.49 +(:import java.io.File)
   26.50 +(:import [java.util Calendar Date])
   26.51 +
   26.52 +)
   26.53 +
   26.54 +
   26.55 +
   26.56 +
   26.57 +
   26.58 +(defn range-sum 
   26.59 +  "calculates the sum of a range.  Takes the exact same arguments
   26.60 +  as clojure.core/range equilivent to (reduce + (range start end step)), but O(1)."
   26.61 +  ([end]
   26.62 +     (/ (* end (- end 1) ) 2))
   26.63 +  
   26.64 +  ([start end]
   26.65 +     (- (range-sum end) (range-sum start)))
   26.66 +
   26.67 +  ([start end step]
   26.68 +     (letfn [(zero-sum [end step] (* step (range-sum 0 (ceil (/ end step)))))]
   26.69 +     (+ (zero-sum (- end start) step) (* start (int (/ (- end start) step)))))))
   26.70 +
   26.71 +
   26.72 +
   26.73 +(defn range-sum-squares
   26.74 +  "equivalent to (reduce + (map #(expt % 2) (range start end step))), 
   26.75 +   but runs in O(1) time."
   26.76 +  ([end]
   26.77 +     (let [n (- end 1)]
   26.78 +     (- (* (expt n 3) 1/3) ;continous volume
   26.79 +	(+ (* -1/6 n) (* -1/2 (expt n 2)))))) ;discrete correction
   26.80 +
   26.81 +   ([start end]
   26.82 +     (- (range-sum-squares end) (range-sum-squares start)))
   26.83 +
   26.84 +   ([start end step]
   26.85 +      ;; (letfn [(zero-sum-squares [end step]
   26.86 +      ;; 				(* step step (range-sum-squares 0 (ceil (/ end step)))))]
   26.87 +      ;; 	(+ 
   26.88 +      ;; 	 (* 2 step (range-sum (ceil (/ (- end start) step))))
   26.89 +      ;; 	 (zero-sum end step) 
   26.90 +      ;; 	 (* start start (int (/ (- end start) step)))))))
   26.91 +))	
   26.92 +
   26.93 +
   26.94 +(defn prime-factors 
   26.95 +  "all the prime factors of the number n"
   26.96 +  [n]
   26.97 +  (filter #(= 0 (rem n %)) (for [p primes :while (<= p n)] p)))
   26.98 +
   26.99 +(defn factor? [a b] (= 0 (rem a b)))
  26.100 +
  26.101 +(defn factor-map [a b]
  26.102 +  (if (factor? a b) 
  26.103 +	{b (quot a b)}
  26.104 +	nil))
  26.105 +
  26.106 +
  26.107 +(defn divides? [numerator divisor] (= (rem numerator divisor) 0))
  26.108 +
  26.109 +
  26.110 +(def != (comp not =))
  26.111 +
  26.112 +
  26.113 +(defn decompose [number factor]
  26.114 +    (loop [n number counter 0]
  26.115 +      (if (!= (rem n factor) 0)
  26.116 +        counter
  26.117 +	(recur (/ n factor) (inc counter)))))
  26.118 +
  26.119 +	
  26.120 +
  26.121 +
  26.122 +
  26.123 +
  26.124 +
  26.125 +(defn single-factor [{num :current-num index :prime-index factors :prime-factors :as old-state}]
  26.126 +  (let [divisor (nth primes index)
  26.127 +	new-index (inc index)
  26.128 +	done? (= num 1)]
  26.129 +    (if (divides? num divisor)
  26.130 +      (let [new-num (/ num (expt divisor (decompose num divisor)))   
  26.131 +	    factors (assoc factors divisor (decompose num divisor))]
  26.132 +	[[factors done?] (assoc old-state
  26.133 +		 :current-num new-num :prime-index new-index :prime-factors factors)])
  26.134 +      
  26.135 +      [[factors done?] (assoc old-state 
  26.136 +	       :current-num num :prime-index new-index :prime-factors factors)])))
  26.137 +      
  26.138 +
  26.139 +(defn wtf "a is not used" [a] (domonad state-m [part single-factor] part))
  26.140 +
  26.141 +(defn fuck-it [] 
  26.142 +  (domonad state-m 
  26.143 +	   [[factors done?]
  26.144 +	    (state-m-until second wtf nil)]
  26.145 +	   
  26.146 +	   factors))
  26.147 +
  26.148 +(defn prime-factor-map [num]
  26.149 +  
  26.150 +  (first ((fuck-it) {:prime-factors {}
  26.151 +		     :prime-index 0
  26.152 +		     :current-num num})))
  26.153 +
  26.154 +(defn prime-factors-monad [num]
  26.155 +  (sort (keys (prime-factor-map num))))
  26.156 +
  26.157 +
  26.158 +
  26.159 +
  26.160 +
  26.161 +
  26.162 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  26.163 +;; fun with state monad
  26.164 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  26.165 +
  26.166 +
  26.167 +(defn ++ [{num :num :as world}]
  26.168 +  (let [num++ (inc num)]
  26.169 +    [num++ (assoc world :num num++)]))
  26.170 +
  26.171 +(defn huh? []
  26.172 +  (with-monad state-m 
  26.173 +    (domonad [x ++
  26.174 +	      y ++]
  26.175 +	     y)))
  26.176 +
  26.177 +
  26.178 +(comment 
  26.179 +
  26.180 +huh?
  26.181 +->
  26.182 +((let [m-bind (fn m-bind-state [mv f]
  26.183 +		(fn [s]
  26.184 +		  (let [[v ss] (mv s)]
  26.185 +		    ((f v) ss))))] 
  26.186 +       (m-bind
  26.187 +	++ (fn [x] ++))) {:num 1})
  26.188 +
  26.189 +
  26.190 +)
  26.191 +
  26.192 +
  26.193 +(defn wordify [n] (cl-format nil "~R" n))
  26.194 +    
  26.195 +(defn british-letter-count-prof [n]
  26.196 +  (prof :total
  26.197 +  (let [and? (prof :rem-test (if (and (> n 99) (!= 0 (rem n 100))) 3 0))
  26.198 +	word (prof :wordify (wordify n))
  26.199 +	word-seq (prof :sequence (seq word))
  26.200 +	word-filter (prof :filter (filter #(Character/isLetter %) word-seq))
  26.201 +	word-count (prof :count (count word-filter))
  26.202 +	answer (prof :add (+ and? word-count))]
  26.203 +    answer)))
  26.204 +
  26.205 +(defn british-letter-count-prof2 
  26.206 +"now this is faster, because it uses string manipulation.  go profiling!"
  26.207 +[n]
  26.208 +  (prof :total
  26.209 +  (let [and? (prof :rem-test (if (and (> n 99) (!= 0 (rem n 100))) 3 0))
  26.210 +	word (prof :wordify (wordify n))
  26.211 +	word-regex (prof :regex (re-gsub #"[\W-,]" "" word))
  26.212 +	
  26.213 +	word-count (prof :count (.length word-regex))
  26.214 +	answer (prof :add (+ and? word-count))]
  26.215 +    answer)))
  26.216 +
  26.217 +
  26.218 +   
  26.219 +
  26.220 +
  26.221 +
  26.222 +
  26.223 +
  26.224 +
  26.225 +
  26.226 +
  26.227 +
  26.228 +
  26.229 +
  26.230 +
  26.231 +
  26.232 +
  26.233 +
  26.234 +
  26.235 +;pseudo code for primes
  26.236 +
  26.237 +;fn prime-decomposition
  26.238 +; [n]
  26.239 +; map = {} 
  26.240 +; 
  26.241 +; for x in primes
  26.242 +;   add to map (divide teh fick out n x)
  26.243 +;   n = n / prime-factors
  26.244 +;   if n == 1 BREAK;
  26.245 +;
  26.246 +;
  26.247 +
  26.248 +
  26.249 +
  26.250 +(defn rng [seed]
  26.251 +  (let [m      259200
  26.252 +	value  (/ (float seed) (float m))
  26.253 +	next   (rem (+ 54773 (* 7141 seed)) m)]
  26.254 +    [value next]))
  26.255 +
  26.256 +
  26.257 +(defn yeah! []
  26.258 +  (let [name sequence-m 
  26.259 +	m-bind (:m-bind name) 
  26.260 +	m-result (:m-result name) 
  26.261 +	m-zero (:m-zero name) 
  26.262 +	m-plus (:m-plus name)] 
  26.263 +
  26.264 +
  26.265 +    (m-bind (range 5) (fn [a] (m-bind [2 3] (fn [b] (m-result (+ a b))))))))
  26.266 +
  26.267 +
  26.268 +(defn ohhhh!! []
  26.269 +  
  26.270 +  (let 
  26.271 +      [name state-m 
  26.272 +       m-bind (:m-bind name) 
  26.273 +       m-result (:m-result name) ]
  26.274 +    
  26.275 +    (m-bind rng (fn [x1] (m-bind rng (fn [x2] (m-result (+ x1 x2))))))))
  26.276 +
  26.277 +
  26.278 +
  26.279 +(defmulti palindrome? class)
  26.280 +  
  26.281 +(defmethod palindrome? (class "string") [a]
  26.282 +  (= (seq a) (reverse a)))
  26.283 +
  26.284 +(defmethod palindrome? (class 500) [a]
  26.285 +  (palindrome? (str a)))
  26.286 +
  26.287 +
  26.288 +
  26.289 +
  26.290 +
  26.291 +
  26.292 +
  26.293 +
  26.294 +(defn circulars 
  26.295 +  "returns a vector of all the circular permutations of a number"
  26.296 +  [n]
  26.297 +  (map #(Integer. (apply str %)) (rotations (seq (str n)))))
  26.298 +    
  26.299 +
  26.300 +(defn prime-factors
  26.301 +  [n]
  26.302 +  (for [a primes :while (<= a n) :when (= (rem n a) 0)]  a)) 
  26.303 +
  26.304 +
  26.305 +(defmethod = [nil java.lang.Integer] [ a b ]
  26.306 +  false)
  26.307 +
  26.308 +
  26.309 +
  26.310 +(def mil 1000000)
  26.311 +(def bil 1000000000)
  26.312 +
  26.313 +(defn primes-under-million [] (apply hash-set (take 78498 primes)))
  26.314 +(def primes-under-million (memoize primes-under-million))
  26.315 +
  26.316 +
  26.317 +(defn primes-under-billion [] (apply hash-set (take 664579 primes)))
  26.318 +(def primes-under-billion (memoize primes-under-billion))
  26.319 +
  26.320 +
  26.321 +
  26.322 +
  26.323 +
  26.324 +(defn prime? [n] (not (nil? (get (primes-under-billion) n))))
  26.325 +
  26.326 +
  26.327 +(defn circular-memoize 
  26.328 +  "assumes that f is a predicate that takes in a number for which, 
  26.329 +   if the predicate is true for the number, it is also true for all
  26.330 +   of the circular permutations of the number.  Memoizes the result
  26.331 +   for all circular permutations so as to avoid subsequent computation."
  26.332 +  [f]
  26.333 +   (let [mem (atom {})]
  26.334 +    (fn [n]
  26.335 +      (if-let [e (find @mem n)]
  26.336 +        (val e)
  26.337 +        (let [ret (f n)]
  26.338 +	  (dorun (for [circ (circulars n)]
  26.339 +		   (swap! mem assoc n ret)))
  26.340 +          ret)))))
  26.341 +
  26.342 +(defn circularly-prime?
  26.343 +  [n]
  26.344 +  (not (some (comp not prime?) (circulars n))))
  26.345 +
  26.346 +(def circularly-prime? (memoize circularly-prime?))
  26.347 +
  26.348 +
  26.349 +(defmethod = :default  [& args]
  26.350 +  (apply clojure.core/= args))
  26.351 +  
  26.352 +(def logins 
  26.353 +     (map str
  26.354 +	  [319 680 180 690 129 620 762 689 762 318
  26.355 +	   368 710 720 710 629 168 160 689 716 731
  26.356 +	   736 729 316 729 729 710 769 290 719 680
  26.357 +	   318 389 162 289 162 718 729 319 790 680
  26.358 +	   890 362 319 760 316 729 380 319 728 716]))
  26.359 +
  26.360 +(defn remove-multiples [n]
  26.361 +  (reduce (fn [a b] (if (= (last a) b) a (conj a b))) [] n))
  26.362 +
  26.363 +(defn insert [item n vect]
  26.364 +  (let [split (split-at n vect)]
  26.365 +    (apply vector (flatten [(first split) item (last split)]))))
  26.366 +
  26.367 +(defn expand-code [old-code [c b a]]
  26.368 +  (let [main-length (count old-code)]
  26.369 +    (for [x (range (inc main-length)) y (range (inc x)) z (range (inc y))] 
  26.370 +      (insert c z (insert b y (insert a x old-code)))))) 
  26.371 +
  26.372 +(defn domain-expand-contract [old-domain constraint]
  26.373 +  (let [new-domain 
  26.374 +	(map remove-multiples 
  26.375 +	     (remove-multiples 
  26.376 +	      (sort 
  26.377 +	       (apply concat 
  26.378 +		      (map #(expand-code % constraint) old-domain)))))
  26.379 +	min-code-length (apply min (map count new-domain)) ]
  26.380 +    (map #(apply str %) (filter #(= (count %) min-code-length) new-domain))))
  26.381 +(def domain-expand-contract (memoize domain-expand-contract))
  26.382 +
  26.383 +
  26.384 +
  26.385 +(defn lazy-fibo 
  26.386 +  ([] (concat [0 1] (lazy-fibo 0 1)))
  26.387 +  ([a b] (let [n (+ a b)] (lazy-seq (cons n (lazy-fibo b n))))))
  26.388 +
  26.389 +
  26.390 +(defn collatz-seq [n]  
  26.391 +  (lazy-seq
  26.392 +  (cond (= n 1) [1]
  26.393 +	(even? n) (lazy-seq (cons n (collatz-seq (/ n 2))))
  26.394 +	(odd? n)  (lazy-seq (cons n (collatz-seq (+ 1 (* 3 n))))))))
  26.395 +(def collatz-seq (memoize collatz-seq))
  26.396 +
  26.397 +
  26.398 +
  26.399 +(defn pythagorean-triple? [a b c]
  26.400 +  (let [[a b c] (sort [a b c])]
  26.401 +    (= (+ (* a a) (* b b) ) (* c c))))
  26.402 +
  26.403 +
  26.404 +(defn sum-squares [coll]
  26.405 +  (reduce +  (map #(* % %) coll)))
  26.406 +
  26.407 +
  26.408 +(defn british-letter-count [n]
  26.409 +  
  26.410 +  (let [and? (if (and (> n 99) (!= 0 (rem n 100))) 3 0)]
  26.411 +
  26.412 +    (+ and? (count (filter #(Character/isLetter %) (seq (wordify n)))))))
  26.413 +
  26.414 +
  26.415 +
  26.416 +(defmacro apply-macro
  26.417 +  "This is evil.  Don't ever use it.  It makes a macro behave like a
  26.418 +  function.  Seriously, how messed up is that?
  26.419 +
  26.420 +  Evaluates all args, then uses them as arguments to the macro as with
  26.421 +  apply.
  26.422 +
  26.423 +  (def things [true true false])
  26.424 +  (apply-macro and things)
  26.425 +  ;; Expands to:  (and true true false)"
  26.426 +  [macro & args]
  26.427 +  (cons macro (flatten (map eval args))))
  26.428 +
  26.429 +(defn fun1 [] (Thread/sleep 5000) 5)
  26.430 +
  26.431 +(defn fun2 [] (Thread/sleep 30000) 5)
  26.432 +
  26.433 +
  26.434 +(def naturals (iterate inc 0))
  26.435 +  
  26.436 +
  26.437 +
  26.438 +
  26.439 +(defn race []
  26.440 +  (let [result (ref nil)
  26.441 +	threads [(Thread. (fn [] (try 
  26.442 +				  (let [answer (fun1)] 
  26.443 +				    (dosync (ref-set result answer)))
  26.444 +				  (catch Exception _ nil))))
  26.445 +		 (Thread. (fn [] (try 
  26.446 +				  (let [answer (fun2)] 
  26.447 +				    (dosync (ref-set result answer))) 
  26.448 +				  (catch Exception _ nil))))]]
  26.449 +	   
  26.450 +    (dorun (map #(.start %) threads))
  26.451 +    (loop []
  26.452 +      (if (!= (deref result) nil)
  26.453 +	(do (dorun (map #(.stop %) threads))
  26.454 +	    (deref result))
  26.455 +	(recur)))))
  26.456 +
  26.457 +
  26.458 +
  26.459 +
  26.460 +
  26.461 +
  26.462 +
  26.463 +(defn make-date [year month day] (do (let [date (Calendar/getInstance)] (.set date year month day 0 0) date)))
  26.464 +
  26.465 +(def jan-1-1901 (make-date 1900 0 1))
  26.466 +
  26.467 +(defn sunday? [#^java.util.Calendar date] (= 7 (.getDay (.getTime date))))
  26.468 +
  26.469 +
  26.470 +
  26.471 +
  26.472 +
  26.473 +
  26.474 +(comment
  26.475 +
  26.476 +;; ----------------------------------------------------------------------
  26.477 +;; Answers
  26.478 +;; ----------------------------------------------------------------------
  26.479 +
  26.480 +; Problem 1 
  26.481 +(+ (range-sum 0 1001 3) (range-sum 0 1001 5) (* -1 (range-sum 0 1001 15)))
  26.482 +
  26.483 +; Problem 2
  26.484 +(reduce + (for [a (filter even? (fibs)) :while (<= a 4000000 )] a))
  26.485 +
  26.486 +; Problem 3
  26.487 +(apply max (prime-factors 600851475143))
  26.488 +
  26.489 +; Problem 4
  26.490 +(reduce max (for [a (range 100 1000) b (range 100 1000) :when (palindrome? (* a b))] (* a b)))
  26.491 +
  26.492 +; Problem 5
  26.493 +(reduce lcm (range 1 21))
  26.494 +
  26.495 +; Problem 6
  26.496 +(- (expt (range-sum 101) 2) (range-sum-squares 101))
  26.497 +
  26.498 +; Problem 7
  26.499 +(nth primes 10000)
  26.500 +
  26.501 +
  26.502 +; Problem 9
  26.503 +(reduce * (first (for [a (range 1 1000) b (range 1 a) c [(sqrt (sum-squares [a b]))] 
  26.504 +      :when (= (+ a b c) 1000)] [a b c])))
  26.505 +
  26.506 +; Problem 10 
  26.507 +(reduce + (for [a primes :while (< a 2000000)] a))
  26.508 +
  26.509 +
  26.510 +
  26.511 +
  26.512 +
  26.513 +; Problem 14
  26.514 +(first (reduce (fn [a b] (if (> (count a) (count b)) a b)) [] (map collatz-seq (range 1 mil))))
  26.515 +
  26.516 +
  26.517 +; Problem 16
  26.518 +(reduce + (map #(Character/getNumericValue %) (seq (str (expt 2 1000)))))
  26.519 +
  26.520 +; Problem 17
  26.521 +(reduce + (map british-letter-count (range 1 1001)))
  26.522 +
  26.523 +
  26.524 +; Problem 24
  26.525 +(nth  (lex-permutations [ 0 1 2 3 4 5 6 7 8 9]) (- mil 1))
  26.526 +
  26.527 +; Problem 33
  26.528 +(reduce * (for [num (range 1 10) 
  26.529 +      den (range 1  10) 
  26.530 +      weird (range 1 10) 
  26.531 +      top [(+ num (* 10 weird))]
  26.532 +      bottom [(+ weird (* 10 den))]
  26.533 +      :when (and (> (/ top bottom) 1) (= (/ top bottom) (/ num den)))]
  26.534 +  (/ bottom top)))
  26.535 +
  26.536 +; Problem 35
  26.537 +(count (filter circularly-prime? (primes-under-million)))
  26.538 +
  26.539 +; Problem 40 
  26.540 +(let [fff (apply str (take 1030000 naturals))] 
  26.541 +  (reduce * (map #(Character/getNumericValue (nth fff %)) 
  26.542 +		 (map (fn [x] (expt 10 x)) (range 7)) )))
  26.543 +
  26.544 +
  26.545 +
  26.546 +
  26.547 +
  26.548 +
  26.549 +; Problem 79
  26.550 +(reduce domain-expand-contract [""] logins)
  26.551 +
  26.552 +)
  26.553 +
  26.554 +
  26.555 +
  26.556 +
  26.557 +
  26.558 +
  26.559 +
  26.560 +
  26.561 +
  26.562 +
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/src/clojureDemo/rlm.clj~	Fri Aug 20 00:32:44 2010 -0400
    27.3 @@ -0,0 +1,67 @@
    27.4 +(ns clojureDemo.rlm
    27.5 +
    27.6 +(:refer-clojure :exclude [+ - / * 
    27.7 +			  assoc conj dissoc empty get into seq
    27.8 +			  = < > <= >= zero?
    27.9 +			  ])
   27.10 +
   27.11 +(:use [clojure.contrib.generic
   27.12 +	 arithmetic
   27.13 +	 collection
   27.14 +	 comparison
   27.15 +	 ])
   27.16 +
   27.17 +(:use [clojure.contrib
   27.18 +         accumulators
   27.19 +	 combinatorics
   27.20 +	 repl-utils
   27.21 +	 def
   27.22 +	 duck-streams
   27.23 +	 shell-out
   27.24 +	 import-static
   27.25 +	 lazy-seqs
   27.26 +	 logging
   27.27 +	 map-utils
   27.28 +	 math
   27.29 +	 mock
   27.30 +	 monads
   27.31 +	 ns-utils
   27.32 +	 ])
   27.33 +
   27.34 +(:use [clojure.contrib.pprint :exclude [write]])
   27.35 +  
   27.36 +(:use [clojure.contrib.pprint.examples
   27.37 +	 hexdump
   27.38 +	 json
   27.39 +	 multiply
   27.40 +	 props
   27.41 +	 show-doc
   27.42 +	 xml
   27.43 +	 ])
   27.44 +
   27.45 +(:import java.io.File)
   27.46 +
   27.47 +
   27.48 +
   27.49 +)
   27.50 +
   27.51 +
   27.52 +  
   27.53 +  
   27.54 +
   27.55 +
   27.56 +
   27.57 +(defn rlm-extra-load []
   27.58 +  (use :reload-all
   27.59 +       '[ clojureDemo
   27.60 +	 rlm
   27.61 +	 project-euler
   27.62 +	 ]))
   27.63 + 
   27.64 +
   27.65 +(defn rlm-switch []
   27.66 +  (in-ns 'rlm)
   27.67 +  (rlm-extra-load))
   27.68 +
   27.69 +(defn switch-rlm []
   27.70 +  (rlm-switch))
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/src/clojureDemo/sys-utils.clj~	Fri Aug 20 00:32:44 2010 -0400
    28.3 @@ -0,0 +1,49 @@
    28.4 +(ns clojureDemo.sys-utils
    28.5 +
    28.6 +:use [clojure.contrib duck-streams str-utils shell-out]
    28.7 +:import java.io.File
    28.8 +)
    28.9 +
   28.10 +
   28.11 +
   28.12 +
   28.13 +(defn escape-spaces
   28.14 +  [string]
   28.15 +  (re-gsub #" " (str \-) string))
   28.16 +
   28.17 +
   28.18 +(defn view 
   28.19 +  [string]
   28.20 +  (seq (char-array string)))
   28.21 +
   28.22 +(defn parent-source [target file]
   28.23 +  (File. (str target "/" (.getName (.getParentFile file))"-" (.getName file))))
   28.24 +
   28.25 +
   28.26 +(defn rsync [file1 file2]
   28.27 +  (let [*out* nil]
   28.28 +  (sh "rsync" "-avz" (str file1) (escape-spaces(str file2)))))
   28.29 +
   28.30 +(defn shunt-file [target file]
   28.31 +  (rsync (str file) (str (parent-source target file)))) 
   28.32 +	
   28.33 +	  
   28.34 +
   28.35 +(defn extract-files
   28.36 +  [regex source destination]
   28.37 +
   28.38 +  (map (partial shunt-file destination) 
   28.39 +  (filter (comp not nil? (partial re-matches regex) str)  (file-seq source))))
   28.40 +
   28.41 +(defn test-extract
   28.42 +  []
   28.43 +  ((partial extract-files #".*\.JPG"
   28.44 +	    (file-str " /home/r/Desktop/judy_yates_computer_archive/MyDocuments/dallas townhome") 
   28.45 +	    (file-str "/home/r/Desktop/judyates_admin/archive-source-images/"))))
   28.46 +
   28.47 +
   28.48 +(defn judy-jpg-extract
   28.49 +  []
   28.50 +  ((partial extract-files #".*\.JPG"
   28.51 +	    (file-str "/home/r/Desktop/judy_yates_computer_archive") 
   28.52 +	    (file-str "/home/r/Desktop/judyates_admin/archive-source-images/"))))
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/src/clojureDemo/sys_utils.clj	Fri Aug 20 00:32:44 2010 -0400
    29.3 @@ -0,0 +1,69 @@
    29.4 +
    29.5 +(ns clojureDemo.sys-utils
    29.6 +
    29.7 +(:use [clojure.contrib duck-streams str-utils shell-out])
    29.8 +(:import java.io.File)
    29.9 +)
   29.10 +
   29.11 +
   29.12 +
   29.13 +(defn rename [file]
   29.14 +
   29.15 +  (if (re-matches #".*\.JPG$" (str file))
   29.16 +    (sh "mv" (str file)  (re-sub #"\.JPG" ".jpg" (str file)))
   29.17 +    nil))
   29.18 +
   29.19 +
   29.20 +
   29.21 +
   29.22 +(defn escape-spaces
   29.23 +  [string]
   29.24 +  (re-gsub #" " (str \-) string))
   29.25 +
   29.26 +
   29.27 +(defn view 
   29.28 +  [string]
   29.29 +  (seq (char-array string)))
   29.30 +
   29.31 +(defn parent-source [target file]
   29.32 +  (File. (str target "/" (.getName (.getParentFile file))"-" (.getName file))))
   29.33 +
   29.34 +
   29.35 +(defn rsync [file1 file2]
   29.36 +  (let [*out* nil]
   29.37 +  (sh "rsync" "-avz" (str file1) (escape-spaces(str file2)))))
   29.38 +
   29.39 +(defn shunt-file [target file]
   29.40 +  (rsync (str file) (str (parent-source target file)))) 
   29.41 +	
   29.42 +	  
   29.43 +
   29.44 +(defn extract-files
   29.45 +  [regex source destination]
   29.46 +
   29.47 +  (dorun (map (partial shunt-file destination) 
   29.48 +  (filter (comp not nil? (partial re-matches regex) str)  (file-seq source)))))
   29.49 +
   29.50 +
   29.51 +(defn file-count [#^java.io.File file]
   29.52 +  (count (file-seq file)))
   29.53 +  
   29.54 +
   29.55 +
   29.56 +
   29.57 +(comment
   29.58 +
   29.59 +(defn test-extract
   29.60 +  []
   29.61 +  ((partial extract-files #".*\.JPG"
   29.62 +	    (file-str " /home/r/Desktop/judy_yates_computer_archive/MyDocuments/dallas townhome") 
   29.63 +	    (file-str "/home/r/Desktop/judyates_admin/archive-source-images/"))))
   29.64 +
   29.65 +
   29.66 +(defn judy-jpg-extract
   29.67 +  []
   29.68 +  ((partial extract-files #".*\.JPG"
   29.69 +	    (file-str "/home/r/Desktop/judy_yates_computer_archive") 
   29.70 +	    (file-str "/home/r/Desktop/judyates_admin/archive-source-images/"))))
   29.71 +
   29.72 +)
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/src/clojureDemo/sys_utils.clj~	Fri Aug 20 00:32:44 2010 -0400
    30.3 @@ -0,0 +1,61 @@
    30.4 +
    30.5 +(ns clojureDemo.sys-utils
    30.6 +
    30.7 +(:use [clojure.contrib duck-streams str-utils shell-out])
    30.8 +(:import java.io.File)
    30.9 +)
   30.10 +
   30.11 +
   30.12 +
   30.13 +
   30.14 +(defn escape-spaces
   30.15 +  [string]
   30.16 +  (re-gsub #" " (str \-) string))
   30.17 +
   30.18 +
   30.19 +(defn view 
   30.20 +  [string]
   30.21 +  (seq (char-array string)))
   30.22 +
   30.23 +(defn parent-source [target file]
   30.24 +  (File. (str target "/" (.getName (.getParentFile file))"-" (.getName file))))
   30.25 +
   30.26 +
   30.27 +(defn rsync [file1 file2]
   30.28 +  (let [*out* nil]
   30.29 +  (sh "rsync" "-avz" (str file1) (escape-spaces(str file2)))))
   30.30 +
   30.31 +(defn shunt-file [target file]
   30.32 +  (rsync (str file) (str (parent-source target file)))) 
   30.33 +	
   30.34 +	  
   30.35 +
   30.36 +(defn extract-files
   30.37 +  [regex source destination]
   30.38 +
   30.39 +  (dorun (map (partial shunt-file destination) 
   30.40 +  (filter (comp not nil? (partial re-matches regex) str)  (file-seq source)))))
   30.41 +
   30.42 +
   30.43 +(defn file-count [#^java.io.File file]
   30.44 +  (count (file-seq file)))
   30.45 +  
   30.46 +
   30.47 +
   30.48 +
   30.49 +(comment
   30.50 +
   30.51 +(defn test-extract
   30.52 +  []
   30.53 +  ((partial extract-files #".*\.JPG"
   30.54 +	    (file-str " /home/r/Desktop/judy_yates_computer_archive/MyDocuments/dallas townhome") 
   30.55 +	    (file-str "/home/r/Desktop/judyates_admin/archive-source-images/"))))
   30.56 +
   30.57 +
   30.58 +(defn judy-jpg-extract
   30.59 +  []
   30.60 +  ((partial extract-files #".*\.JPG"
   30.61 +	    (file-str "/home/r/Desktop/judy_yates_computer_archive") 
   30.62 +	    (file-str "/home/r/Desktop/judyates_admin/archive-source-images/"))))
   30.63 +
   30.64 +)
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/src/laser/.#rasterize.clj	Fri Aug 20 00:32:44 2010 -0400
    31.3 @@ -0,0 +1,1 @@
    31.4 +r@RLM.3097:1282277171
    31.5 \ No newline at end of file
    32.1 --- a/src/laser/rasterize.clj	Thu Aug 19 22:24:41 2010 -0400
    32.2 +++ b/src/laser/rasterize.clj	Fri Aug 20 00:32:44 2010 -0400
    32.3 @@ -25,6 +25,31 @@
    32.4  
    32.5  (def img "/home/r/graster/test.png")
    32.6  
    32.7 +
    32.8 +(def feed 120)
    32.9 +(def  dpi [500, 500])
   32.10 +(def on_range [0.0, 0.5])
   32.11 +(def overshoot 0.5)
   32.12 +(def offset [1.0, 1.0])
   32.13 +(def tiles [1, 1])
   32.14 +(def tile_size [false, false])
   32.15 +(def tile_spacing [0.125, 0.125])
   32.16 +(def feed 120)
   32.17 +(def cut_feed 20)
   32.18 +(def corner_radius 0)
   32.19 +
   32.20 +
   32.21 +
   32.22 +
   32.23 +(defn raster-preamble []
   32.24 +  (str-join \newline
   32.25 +	    ["M63 P0\nG61"
   32.26 +	    (str \F feed)
   32.27 +	    "M101"
   32.28 +	    "M3 S1"]))
   32.29 +
   32.30 +
   32.31 +
   32.32  (defn frame-hash
   32.33    "yields a convienent representation for the pixles in an image.
   32.34     Because of the size of the structvre generated, this must only be used
   32.35 @@ -46,6 +71,42 @@
   32.36        {:width  (.getWidth image+) :height (.getHeight image+)})))
   32.37  
   32.38  
   32.39 +(def white {:r 255, :g 255, :b 255})
   32.40 +(def black {:r 0,   :g 0,   :b 0})
   32.41 +
   32.42 +(def expt #(Math/pow %1 %2))
   32.43 +
   32.44 +(defn rgb-euclidian
   32.45 +  [{r1 :r g1 :g b1 :b} {r2 :r g2 :g b2 :b} ]
   32.46 +  (expt (+ (expt (- r1 r2) 2)
   32.47 +	  (expt (- g1 g2) 2)
   32.48 +	  (expt (- b1 b2) 2)) 0.5))
   32.49 +
   32.50 +(defn b&w
   32.51 +  "turn everything strictly black or white"
   32.52 +  [window]
   32.53 +  (with-meta
   32.54 +  (zipmap
   32.55 +   (keys window)
   32.56 +   (map (fn  [rgb] 
   32.57 +	  (if (> (rgb-euclidian rgb white) (rgb-euclidian rgb black))
   32.58 +	    black white))
   32.59 +	(vals window))) (meta window)))
   32.60 +
   32.61 +
   32.62 +
   32.63 +
   32.64 +
   32.65 +  
   32.66 +  
   32.67 +
   32.68 +
   32.69 +
   32.70 +
   32.71 +
   32.72 +
   32.73 +
   32.74 +
   32.75  (defn frame-hash->bufferedImage
   32.76    [frame-hash]
   32.77      (let [data  (meta frame-hash)