diff src/clojureDemo/VideoTransforms.clj @ 1:6d9bdaf919f7

added clojureDemo source
author Robert McIntyre <rlm@mit.edu>
date Fri, 20 Aug 2010 00:32:44 -0400
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/clojureDemo/VideoTransforms.clj	Fri Aug 20 00:32:44 2010 -0400
     1.3 @@ -0,0 +1,194 @@
     1.4 +(ns clojureDemo.VideoTransforms)
     1.5 +  
     1.6 +(import '(java.awt Rectangle Robot Toolkit) )
     1.7 +(import '(java.awt.image BufferedImage) )
     1.8 +(import '(java.awt Graphics2D Panel))
     1.9 +(import '(java.io File) )
    1.10 +(import '(javax.imageio ImageIO) )
    1.11 +(import '(javax.swing JFrame))
    1.12 +(import '(org.apache.commons.io FileUtils))
    1.13 +(import clojure.lang.LazySeq)
    1.14 +(import '(name.audet.samuel.javacv.jna highgui cv cxcore))
    1.15 +(import '(name.audet.samuel.javacv CanvasFrame))
    1.16 +(import '(name.audet.samuel.javacv.jna cxcore$IplImage))
    1.17 +(import '(name.audet.samuel.javacv.jna highgui$CvCapture$PointerByReference))
    1.18 +(import '(name.audet.samuel.javacv.jna highgui$CvVideoWriter$PointerByReference))
    1.19 +(import '(name.audet.samuel.javacv.jna cxcore$IplImage$PointerByReference))
    1.20 +(import '(name.audet.samuel.javacv.jna cxcore$IplImage))
    1.21 +(import '(name.audet.samuel.javacv JavaCvErrorCallback))
    1.22 +
    1.23 +(.redirectError (JavaCvErrorCallback.));this enables the c errors to travel up to the JVM
    1.24 +                                       ;where they can be handled.
    1.25 +
    1.26 +
    1.27 +(use '[clojureDemo.VisionCore :only (video-seq cache video-data close-writer)])
    1.28 +
    1.29 + 
    1.30 +(use 'clojure.contrib.repl-utils)
    1.31 +
    1.32 +(def -inf Double/NEGATIVE_INFINITY)
    1.33 +(def inf  Double/POSITIVE_INFINITY)
    1.34 +
    1.35 +
    1.36 +(def lian (File. "/home/r/Desktop/source-videos/lian1.mpeg"))
    1.37 +(def look (File. "/home/r/Desktop/source-videos/dramatic_look.flv"))
    1.38 +(def getto(File. "/home/r/Desktop/source-videos/Ghetto.flv"))
    1.39 +(def human0(File. "/home/r/Desktop/source-videos/vsr1/human0.avi"))
    1.40 +
    1.41 +(def base (File. "/home/r/Desktop/source-videos/"))
    1.42 +
    1.43 +(def app0 (File. base "approach0v2.avi"))
    1.44 +(def app1 (File. base "approach1v3.avi"))
    1.45 +(def app2 (File. base "approach0v3.avi"))
    1.46 +(def app3 (File. base "approach2v2.avi"))
    1.47 +(def app4 (File. base "approach1v2.avi")) 
    1.48 +(def app5 (File. base "approach2v3.avi"))
    1.49 +  
    1.50 +(def bounce0 (File. base "bounce0v2.avi"))  
    1.51 +(def bounce1 (File. base "bounce1v3.avi")) 
    1.52 +(def bounce2 (File. base "bounce3v2.avi"))
    1.53 +(def bounce3 (File. base "bounce0v3.avi"))  
    1.54 +(def bounce4 (File. base "bounce2v2.avi"))
    1.55 +(def bounce5 (File. base "bounce1v2.avi"))  
    1.56 +(def bounce6 (File. base "bounce2v3.avi"))
    1.57 +
    1.58 +(def collide0 (File. base "collide0v3.avi"))  
    1.59 +(def collide1 (File. base "collide2v3.avi")) 
    1.60 +(def collide2 (File. base "collide1v2.avi"))
    1.61 +(def collide3 (File. base "collide0v2.avi"))  
    1.62 +(def collide4 (File. base "collide1v3.avi")) 
    1.63 +  
    1.64 +(def give0 (File. base "give0v3.avi"))  
    1.65 +(def give1 (File. base "give2v3.avi")) 
    1.66 +(def give2 (File. base "give1v2.avi")) 
    1.67 +(def give3 (File. base "give0v2.avi"))        
    1.68 +(def give4 (File. base "give1v3.avi"))
    1.69 +
    1.70 +
    1.71 +(def target (File. "/home/r/Desktop/output-vision/"))
    1.72 +(def default(File. target "default.avi"))
    1.73 +(defn- makePanel [image] (proxy [Panel] [] (paint [g]  (.drawImage g image 0 0 nil))))
    1.74 +
    1.75 +(defmulti  display "Creates a JFrame and displays a buffered image"  class)
    1.76 +
    1.77 +(defmethod display 
    1.78 +  BufferedImage  [image] 
    1.79 +  (let [panel (makePanel image)
    1.80 +	frame (JFrame. "Oh Yeah!")]
    1.81 +    (.add frame panel) 
    1.82 +    (.pack frame) 
    1.83 +    (.setVisible frame true ) 
    1.84 +    (.setSize frame(.getWidth image) (.getHeight image))))
    1.85 +
    1.86 +(defmethod display
    1.87 +  cxcore$IplImage [image]
    1.88 +  ( display (.getBufferedImage image)))
    1.89 +  
    1.90 +(defmethod display
    1.91 +  String [image]
    1.92 +  (display (highgui/cvLoadImage image highgui/CV_LOAD_IMAGE_COLOR)))
    1.93 +
    1.94 +(defmethod display
    1.95 +  LazySeq [s]
    1.96 +  (display (first s)))
    1.97 +
    1.98 +
    1.99 +(defn video-writer
   1.100 +  "uses data about the video to make a writer"
   1.101 +  [data fileTarget]
   1.102 +  (highgui/cvCreateVideoWriter 
   1.103 +   (str fileTarget)
   1.104 +   
   1.105 +   ;(highgui/CV_FOURCC \P,\I,\M,\1) ;= MPEG-1 codec  (112913.386195 msecs) (104 MB)
   1.106 +   ;(highgui/CV_FOURCC \M,\J,\P,\G) ;= motion-jpeg codec (crashed)
   1.107 +   ;(highgui/CV_FOURCC \M,\P,\4,\2) ;= MPEG-4.2 codec (107184.186774 msecs) (82 MB)
   1.108 +   ;(highgui/CV_FOURCC \D,\I,\V,\3) ;= MPEG-4.3 codec (118308.933328 msecs)  (83 MB)
   1.109 +   ;;(highgui/CV_FOURCC \D,\I,\V,\X) ;= MPEG-4 codec    (99037.738131 msecs)  (85 MB)
   1.110 +   (highgui/CV_FOURCC \H,\D,\Y,\C)
   1.111 +   ;(highgui/CV_FOURCC \U,\2,\6,\3) ;= H263 codec     (101141.993551 msecs) (89 MB)
   1.112 +   ;(highgui/CV_FOURCC \I,\2,\6,\3) ;= H263I codec      (crashed)
   1.113 +   ;(highgui/CV_FOURCC \F,\L,\V,\1) ;= FLV1 codec     (104307.567802 msecs) (93 MB)
   1.114 +   ;(:codec data)                    ;= whatever the movie originally had.  (98278.694169 msecs) (1.9 GB)  
   1.115 +
   1.116 +   (:fps data) (cxcore/cvSize (:width data) (:height data)) 
   1.117 +   1; 1 here means that we're writing in color.
   1.118 +    ; you cannot change it to 0 to write in 
   1.119 +    ; black and white. Everything just crashes instead.
   1.120 +    ; what a useful paramater.
   1.121 +   ))
   1.122 +
   1.123 +
   1.124 +(defn naturals []  (iterate inc 0))
   1.125 +
   1.126 +
   1.127 +(defn write-frame
   1.128 +  [writer frame]
   1.129 +  (do
   1.130 +    (highgui/cvWriteFrame writer frame)
   1.131 +    frame))
   1.132 +
   1.133 +(defn number-seq
   1.134 +  [video-seq]
   1.135 +  (map #(vector %1 %2) (naturals) video-seq))
   1.136 +
   1.137 +(defn save-seq 
   1.138 +  [writer video-seq]
   1.139 +  (map #(write-frame writer %) video-seq))
   1.140 +  
   1.141 +(defn create-runonce [function]
   1.142 +  (let [sentinel (Object.)
   1.143 +	result (atom sentinel)]
   1.144 +    (fn [& args]
   1.145 +      (locking sentinel
   1.146 +	(if (= @result sentinel)
   1.147 +	  (reset! result (function))
   1.148 +	  @result)))))
   1.149 +
   1.150 +(defmacro oncer 
   1.151 +  [video-seq-gen]
   1.152 +  `((create-runonce #(~@video-seq-gen))))
   1.153 +
   1.154 +(defmacro trans-save
   1.155 +"there's a small problem with trans-save --- it IS
   1.156 +truly transitive, but it does too much work....
   1.157 +sometimes it writes files twice.
   1.158 +this is functionally correct though."
   1.159 +  [target config video-seq]
   1.160 +  `(let [writer# (video-writer ~config ~target)]
   1.161 +     (do
   1.162 +       (dorun (save-seq writer# ~video-seq))
   1.163 +       (close-writer writer#)
   1.164 +       ~video-seq)))
   1.165 +
   1.166 +(defn save-video
   1.167 +  [video target]
   1.168 +  (let [writer (video-writer (video-data video) target)]
   1.169 +    (do 
   1.170 +      (dorun (map #(write-frame writer %) (video-seq video)))
   1.171 +      (close-writer writer))))
   1.172 +
   1.173 +
   1.174 +(comment (Examples of things you can try that will actually work)
   1.175 +
   1.176 +(def lazy-human (video-seq human0)) ;makes a lazy sequence of frames and returns instantly.
   1.177 +(def target1 (File. "some/path/out1.avi")) ;just creates a normal Java File object.
   1.178 +(def target2 (File. "some/other/path/out2.avi"))
   1.179 +(def human0-data (video-data human0)) ;creates a map containing the fps, width, and height of the video. 
   1.180 +
   1.181 +(trans-save target human0-data (video-seq human0))
   1.182 +;saves a copy of human0 to disk.
   1.183 +
   1.184 +(trans-save target2 human0-data (video-seq-filter (trans-save target1 human0-data (video-seq human0))))
   1.185 +;saves an unaltered copy of human0 to disk, filters the sequence of 
   1.186 +;Intel Processing Library images by video-seq-filter, and writes the 
   1.187 +;filtered result to disk.  video-seq-filter could discard every other frame,
   1.188 +;take the sequence by fives and do temporal blurring, or just turn every
   1.189 +;frame to black and white. 
   1.190 +
   1.191 +
   1.192 +(do (use :reload-all 'clojureDemo.VideoTransforms) (in-ns 'clojureDemo.VideoTransforms))
   1.193 +
   1.194 +)
   1.195 +
   1.196 + 
   1.197 +