Mercurial > lasercutter
diff src/clojureDemo/VideoParse.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/VideoParse.clj Fri Aug 20 00:32:44 2010 -0400 1.3 @@ -0,0 +1,230 @@ 1.4 +(ns clojureDemo.VideoParse) 1.5 + 1.6 + 1.7 + 1.8 +;this file is not used anymore, except for the (display %) function. 1.9 + 1.10 + 1.11 + 1.12 +(import '(java.awt Rectangle Robot Toolkit) ) 1.13 +(import '(java.awt.image BufferedImage) ) 1.14 +(import '(java.awt Graphics2D Panel)) 1.15 +(import '(java.io File) ) 1.16 +(import '(javax.imageio ImageIO) ) 1.17 +(import '(com.xuggle.mediatool ToolFactory)) 1.18 +(import '(com.xuggle.mediatool IMediaDebugListener IMediaDebugListener$Event)) 1.19 +(import '(com.xuggle.mediatool MediaToolAdapter)) 1.20 +(import '(com.xuggle.xuggler IContainer IContainer$Type IPacket)) 1.21 +(import '(javax.swing JFrame)) 1.22 + 1.23 +(import clojure.lang.LazySeq) 1.24 + 1.25 +(import '(name.audet.samuel.javacv.jna highgui cv cxcore)) 1.26 + 1.27 +(import '(name.audet.samuel.javacv CanvasFrame)) 1.28 + 1.29 +(import '(name.audet.samuel.javacv.jna cxcore$IplImage)) 1.30 + 1.31 +(import '(name.audet.samuel.javacv.jna highgui$CvCapture$PointerByReference)) 1.32 +(import '(name.audet.samuel.javacv.jna highgui$CvVideoWriter$PointerByReference)) 1.33 + 1.34 +;definitions 1.35 + 1.36 +(def -inf Double/NEGATIVE_INFINITY) 1.37 +(def inf Double/POSITIVE_INFINITY) 1.38 + 1.39 +(use 'clojure.contrib.repl-utils) 1.40 + 1.41 + 1.42 +;minor functions 1.43 + 1.44 +(defn converge 1.45 + "recursively runs update until prior passes accept, then returns" 1.46 + [prior update accept] 1.47 + (if (accept prior) prior (recur (update prior) update accept))) 1.48 + 1.49 +(defn interval-width [interval] (- (last interval) (first interval))) 1.50 + 1.51 +(defn midpoint [interval] 1.52 + (let [a (first interval) b (last interval)] 1.53 + (if (and (= a -inf) (= b inf)) 0 1.54 + (if (= a -inf) (midpoint [(- b 200000) b]) 1.55 + (if (= b inf) (midpoint [a (+ a 200000)]) 1.56 + (int (/ (+ a b) 2))))))) 1.57 + 1.58 +(defn cart2 1.59 + "calculates the cartesian product in 2 dimensions" 1.60 + [point] 1.61 + (let [[x y] point] (for [abscissa (range x) ordinate (range y)] [abscissa ordinate]))) 1.62 + 1.63 +(defn closeCapture 1.64 + [capture] 1.65 + (highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture))) 1.66 + 1.67 +(defn- makePanel [image] (proxy [Panel] [] (paint [g] (.drawImage g image 0 0 nil)))) 1.68 + 1.69 +(defn screenshot "grab screenshot" [] 1.70 + 1.71 + (ImageIO/write 1.72 + (.createScreenCapture (Robot.) (Rectangle. (.getScreenSize (Toolkit/getDefaultToolkit)))) 1.73 + "JPG" 1.74 + (File. "/home/r/Desktop/screenie.jpg"))) 1.75 + 1.76 +(defn- readerRecurse 1.77 + "calls .readPacket until there's nothing left to do" 1.78 + [reader] 1.79 + (if (not (nil? (.readPacket reader))) ; here .readPacket actually does the processing as a side-effect. 1.80 + nil ; it returns null when it has MORE to process, and signals an error when done... 1.81 + (recur reader))) 1.82 + 1.83 +(defmacro times 1.84 + "perform multiple timed tests on a form" 1.85 + [n form] 1.86 + `(dotimes [_# ~n] (time ~form))) 1.87 + 1.88 +(defmacro me-1 1.89 + "does macroexpand-1 without having to quote the form" 1.90 + [form] 1.91 + (list 'macroexpand-1 (list 'quote form))) 1.92 + 1.93 +;Major Functions 1.94 + 1.95 +(defmulti display "Creates a JFrame and displays a buffered image" class) 1.96 + 1.97 +(defmethod display 1.98 + BufferedImage [image] 1.99 + (let [panel (makePanel image) 1.100 + frame (JFrame. "Oh Yeah!")] 1.101 + (.add frame panel) 1.102 + (.pack frame) 1.103 + (.setVisible frame true ) 1.104 + (.setSize frame(.getWidth image) (.getHeight image)))) 1.105 + 1.106 +(defmethod display 1.107 + cxcore$IplImage [image] 1.108 + ( display (.getBufferedImage image))) 1.109 + 1.110 +(defmethod display 1.111 + String [image] 1.112 + (display (highgui/cvLoadImage image highgui/CV_LOAD_IMAGE_COLOR))) 1.113 + 1.114 +(defmethod display 1.115 + LazySeq [s] 1.116 + (display (first s))) 1.117 + 1.118 + 1.119 +(defn convert 1.120 + "takes video and converts it to a new type of video" 1.121 + [videoInput videoOutput] 1.122 + (let [reader (ToolFactory/makeReader videoInput)] 1.123 + (doto reader 1.124 + (.addListener (ToolFactory/makeWriter videoOutput reader)) 1.125 + (.addListener (ToolFactory/makeDebugListener (into-array [IMediaDebugListener$Event/META_DATA])))) 1.126 + (readerRecurse reader))) 1.127 + 1.128 + 1.129 + 1.130 +(defn video-frame 1.131 + ":(" 1.132 + [video frame] 1.133 + (lazy-seq 1.134 + (try 1.135 + (let [capture (highgui/cvCreateFileCapture video)] 1.136 + (highgui/cvSetCaptureProperty capture highgui/CV_CAP_PROP_POS_FRAMES frame) 1.137 + (println (str "Wanted frame <" frame "> but went to keyFrame " (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_POS_FRAMES))) 1.138 + (let [out (highgui/cvQueryFrame capture) 1.139 + image (.clone out)] 1.140 + (highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture)) 1.141 + [image])) 1.142 + (catch java.lang.NullPointerException _ nil)))) 1.143 + 1.144 + 1.145 + 1.146 + 1.147 +(defn save-frame 1.148 + "takes an opencv image and saves it to disk" 1.149 + [frame filename] 1.150 + (highgui/cvSaveImage filename frame)) 1.151 + 1.152 + 1.153 +(defn video-len 1.154 + "finds out the real length of a video in log time." 1.155 + [video] 1.156 + (letfn 1.157 + [ 1.158 + (accept [interval] (= 0 (interval-width interval))) 1.159 + (update [interval] 1.160 + (let [[a b] interval] 1.161 + (if (> (interval-width interval) 2) 1.162 + (let [ 1.163 + middle (midpoint interval) 1.164 + frame (first (video-frame video middle)) 1.165 + ] 1.166 + (if (nil? frame) [a middle] [middle b])) 1.167 + [a a]))) 1.168 + ] 1.169 + 1.170 + (first (converge [-inf inf] update accept)))) 1.171 +(def video-len (memoize video-len)) 1.172 + 1.173 + 1.174 + 1.175 +(defn getData 1.176 + "returns a bunch of stuff about a video" 1.177 + [video] 1.178 + (let 1.179 + [capture (highgui/cvCreateFileCapture video) 1.180 + info {:frames (video-len video) 1.181 + :width (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FRAME_WIDTH) 1.182 + :height (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FRAME_HEIGHT) 1.183 + :fps (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FPS) 1.184 + :codec (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FOURCC)}] 1.185 + 1.186 + (closeCapture capture) 1.187 + info)) 1.188 +(def getData (memoize getData)) 1.189 + 1.190 + 1.191 +(defn sajitify-linear 1.192 + "oh yeah!" 1.193 + [video string] 1.194 + (let [ capture (highgui/cvCreateFileCapture video) 1.195 + frames (:frames (getData video))] 1.196 + (dotimes [n frames] 1.197 + (highgui/cvSaveImage (str string (format "%06d" n) ".jpg") (highgui/cvQueryFrame capture))) 1.198 + (highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture)))) 1.199 + 1.200 +(defn getFrame 1.201 + "gets the frame of a video at the specified time in seconds. 1.202 + this works with the simplest interpolation --- just piecewise steps" 1.203 + [video time] 1.204 + (lazy-seq 1.205 + [time (video-frame video (int (* time (:fps (getData video)))))])) 1.206 + 1.207 +(defn video-seq-times 1.208 + "it's the new and improved version of videoSeq, now using OpenCv. 1.209 + we expect a sequence of times in seconds" 1.210 + [times video] 1.211 + (map #(getFrame video %) times)) 1.212 + 1.213 +(defn video-seq 1.214 + "get's ALL the frames of a video as a lazy sequence of (IplImages)" 1.215 + [video] 1.216 + (take (:frames (getData video)) (map #(video-frame video %) (iterate inc 0)))) 1.217 + 1.218 +(defn trans-Writer 1.219 + "uses data about the video to make a writer" 1.220 + [video fileTarget] 1.221 + (let [data (getData video)] 1.222 + (highgui/cvCreateVideoWriter fileTarget (highgui/CV_FOURCC "F" "L" "V" "1") (:fps data) (cxcore/cvSize (:width data) (:height data)) 1))) 1.223 + 1.224 +(def naturals (iterate inc 0)) 1.225 + 1.226 +(defn sajitify-seq 1.227 + [video string] 1.228 + (dorun (map #(highgui/cvSaveImage (str string (format "%06d" %2) ".jpg") (first %1)) (video-seq video) naturals))) 1.229 + 1.230 + 1.231 + 1.232 + 1.233 +