Mercurial > lasercutter
diff src/clojureDemo/Xuggle.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/Xuggle.clj Fri Aug 20 00:32:44 2010 -0400 1.3 @@ -0,0 +1,221 @@ 1.4 +(ns clojureDemo.Xuggle) 1.5 + 1.6 +(import '(ij ImagePlus IJ)) 1.7 +(import '(java.awt Rectangle Robot Toolkit) ) 1.8 +(import '(java.awt.image BufferedImage) ) 1.9 +(import '(java.awt Graphics2D Panel)) 1.10 +(import '(java.io File) ) 1.11 +(import '(javax.imageio ImageIO) ) 1.12 +(import '(com.xuggle.mediatool ToolFactory)) 1.13 +(import '(com.xuggle.mediatool IMediaDebugListener IMediaDebugListener$Event)) 1.14 +(import '(com.xuggle.mediatool MediaToolAdapter MediaListenerAdapter)) 1.15 +(import '(com.xuggle.xuggler IContainer IContainer$Type IPacket)) 1.16 +(import '(javax.swing JFrame)) 1.17 +(import '(com.xuggle.mediatool IMediaWriter)) 1.18 +(import '(org.apache.commons.io FileUtils)) 1.19 +(import '(javax.imageio.stream FileImageOutputStream)) 1.20 +(import '(javax.imageio ImageWriteParam IIOImage)) 1.21 +(import '(com.xuggle.xuggler IRational)) 1.22 +(import '(java.util.concurrent TimeUnit)) 1.23 +(import '(com.xuggle.xuggler ICodec)) 1.24 + 1.25 +(use 'clojureDemo.Defines) 1.26 +;(use '[clojureDemo.OpenCv :only (video-data)]) 1.27 + 1.28 + 1.29 + 1.30 +(import '(java.io File)) 1.31 +(import '(org.apache.commons.io FileUtils)) 1.32 +(import '(javax.imageio ImageIO) ) 1.33 + 1.34 +(import '(ij.plugin PlugIn)) 1.35 +(import '(ij ImagePlus IJ)) 1.36 + 1.37 + 1.38 +(use 'clojure.contrib.repl-utils) 1.39 +(use ['clojureDemo.Defines 1.40 + :only '( 1.41 + lian look getto human0 blow base app0 app1 app2 app3 app4 app5 1.42 + bounce0 bounce1 bounce2 bounce3 bounce4 bounce5 bounce6 1.43 + collide0 collide1 collide2 collide3 collide4 1.44 + give0 give1 give2 give3 give4 target default)]) 1.45 + 1.46 + 1.47 +;(def hamster (ImagePlus. "lklk" (first (video-seq look)))) 1.48 + 1.49 + 1.50 + 1.51 + 1.52 + 1.53 +(defn- makePanel [image] (proxy [Panel] [] (paint [g] (.drawImage g image 0 0 nil)))) 1.54 + 1.55 + 1.56 +(defmulti display "Creates a JFrame and displays a buffered image" class) 1.57 + 1.58 +(defmethod display 1.59 + BufferedImage [image] 1.60 + (let [panel (makePanel image) 1.61 + frame (JFrame. "Oh Yeah!")] 1.62 + (.add frame panel) 1.63 + (.pack frame) 1.64 + (.setVisible frame true ) 1.65 + (.setSize frame(.getWidth image) (.getHeight image)))) 1.66 + 1.67 +(defmethod display 1.68 + ImagePlus [image] 1.69 + (display (.getBufferedImage image))) 1.70 + 1.71 + 1.72 + 1.73 + 1.74 +(defn flash 1.75 + [image] 1.76 + 1.77 + (.start (Thread. (fn [] 1.78 + (do 1.79 + (.show image) 1.80 + (.updateAndRepaintWindow image) 1.81 + (Thread/sleep 4000) 1.82 + (.hide image)))))) 1.83 + 1.84 + 1.85 +(defn readerRecurse 1.86 + "calls .readPacket until there's nothing left to do" 1.87 + [reader] 1.88 + (if (not (nil? (.readPacket reader))) ; here .readPacket actually does the processing as a side-effect. 1.89 + nil ; it returns null when it has MORE to process, and signals an error when done... 1.90 + (recur reader))) 1.91 + 1.92 + 1.93 +(def *cache-directory* (File. "/home/r/Desktop/vision-cache")) 1.94 +(def *ext* "jpg") 1.95 + 1.96 + 1.97 + 1.98 + 1.99 +(defn writeJpg 1.100 + "WTF is this shit?!" 1.101 + [image target quality] 1.102 + (let [jpgWriter (.next (ImageIO/getImageWritersByFormatName *ext*))] 1.103 + (doto (.getDefaultWriteParam jpgWriter) 1.104 + (.setCompressionMode ImageWriteParam/MODE_EXPLICIT) 1.105 + (.setCompressionQuality quality)) 1.106 + (doto jpgWriter 1.107 + (.setOutput (FileImageOutputStream. target)) 1.108 + (.write (IIOImage. image nil nil)) 1.109 + (.dispose)))) 1.110 + 1.111 + 1.112 + 1.113 +(defn cache-path 1.114 + [video] 1.115 + (File. *cache-directory* (.getName video))) 1.116 + 1.117 +(defn video-frame-path 1.118 + [video n] 1.119 + (File. (cache-path video) (str n "." *ext*))) 1.120 + 1.121 + 1.122 +(defn already-cached 1.123 + "this is the simplest and most retarded way to do it" 1.124 + [video] 1.125 + (.exists (cache-path video))) 1.126 + 1.127 + 1.128 + 1.129 + 1.130 + 1.131 + 1.132 +(defn make-incrementer [start increment] (let [a (ref (- start increment))] (fn [] (dosync (ref-set a (+ @a increment)))))) 1.133 + 1.134 +(defn make-frame-writer 1.135 + [video] 1.136 + (let [incrementer (make-incrementer 0 1)] 1.137 + (proxy [MediaListenerAdapter] [] 1.138 + 1.139 + (onVideoPicture 1.140 + [event] 1.141 + ;(println (.getImage event)) 1.142 + ;(println (File. (cache-path video) (str (incrementer) "." *ext* ) )) 1.143 + 1.144 + (let [target (File. (cache-path video) (str (incrementer) "." *ext* ))] 1.145 + (if (= *ext* "jpg") 1.146 + (writeJpg (.getImage event) target 1) 1.147 + (ImageIO/write (.getImage event) *ext* target ))))))) 1.148 + 1.149 + 1.150 + 1.151 +(defn cache 1.152 + "caching of frames without opencv" 1.153 + [video] 1.154 + 1.155 + (if (already-cached video) 1.156 + nil 1.157 + (time 1.158 + (let [reader (ToolFactory/makeReader (str video))] 1.159 + (println "slow cache!") 1.160 + (FileUtils/forceMkdir (cache-path video)) 1.161 + (doto reader 1.162 + (.setBufferedImageTypeToGenerate BufferedImage/TYPE_3BYTE_BGR) 1.163 + (.addListener (make-frame-writer video)) 1.164 + (.addListener (ToolFactory/makeDebugListener (into-array [IMediaDebugListener$Event/META_DATA])))) 1.165 + (readerRecurse reader))))) 1.166 + 1.167 + 1.168 +(defn video-data 1.169 + "get video data without opencv" 1.170 + [video] (cache video) 1.171 + 1.172 + 1.173 + {:length (- (count (file-seq (cache-path video))) 1) 1.174 + :width (.getWidth (ImagePlus. (str (video-frame-path video 0)))) 1.175 + :height (.getHeight (ImagePlus. (str (video-frame-path video 0)))) 1.176 + :fps 30}) ; yeah --- I'll figure this out later. 1.177 + (def video-data (memoize video-data)) 1.178 + 1.179 + 1.180 + 1.181 +(defn convert 1.182 + "takes video and converts it to a new type of video" 1.183 + [videoInput videoOutput] 1.184 + (let [reader (ToolFactory/makeReader (str videoInput))] 1.185 + (doto reader 1.186 + (.addListener (ToolFactory/makeWriter (str videoOutput) reader)) 1.187 + (.addListener (ToolFactory/makeDebugListener (into-array [IMediaDebugListener$Event/META_DATA])))) 1.188 + (readerRecurse reader))) 1.189 + 1.190 + 1.191 +(import '(com.xuggle.xuggler.video ConverterFactory)) 1.192 + 1.193 + 1.194 +(defn trans-save 1.195 + "this is a transitive way to save a stream to an avi file. 1.196 + It uses meta data to determine what fps to use to encode." 1.197 + [destination video-seq] 1.198 + (let [data (meta video-seq) 1.199 + writer (ToolFactory/makeWriter (str destination)) 1.200 + incrementer (make-incrementer 0 (/ 1 30))] 1.201 + (.addVideoStream writer 0 0 (ICodec/findEncodingCodecByName "mpeg4") 1.202 + (IRational/make (double (:fps data))) 1.203 + (int (:width data)) (int (:height data))) 1.204 + (dorun (map #(.encodeVideo writer 0 1.205 + (ConverterFactory/convertToType (.getBufferedImage %) BufferedImage/TYPE_3BYTE_BGR) 1.206 + (long (* 1000000000 (incrementer))) TimeUnit/NANOSECONDS) video-seq)) 1.207 + (.close writer)) 1.208 + video-seq) 1.209 + 1.210 + 1.211 +(defn video-seq 1.212 + "let's use ImagePlus stuff!" 1.213 + ([video] (cache video) 1.214 + (with-meta (map #(ImagePlus. (str (video-frame-path video %))) (range (:length (video-data video))) ) (video-data video)))) 1.215 + 1.216 + 1.217 + 1.218 + 1.219 + 1.220 + 1.221 +(comment 1.222 + (do (use :reload-all 'clojureDemo.Xuggle) (in-ns 'clojureDemo.Xuggle)) 1.223 +) 1.224 +