Mercurial > lasercutter
view src/clojureDemo/VideoParse.clj @ 21:e72220627685 tip
0.002 inch discrepancy with target. going to test anyway
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 30 Aug 2010 01:19:21 -0400 |
parents | 6d9bdaf919f7 |
children |
line wrap: on
line source
1 (ns clojureDemo.VideoParse)5 ;this file is not used anymore, except for the (display %) function.9 (import '(java.awt Rectangle Robot Toolkit) )10 (import '(java.awt.image BufferedImage) )11 (import '(java.awt Graphics2D Panel))12 (import '(java.io File) )13 (import '(javax.imageio ImageIO) )14 (import '(com.xuggle.mediatool ToolFactory))15 (import '(com.xuggle.mediatool IMediaDebugListener IMediaDebugListener$Event))16 (import '(com.xuggle.mediatool MediaToolAdapter))17 (import '(com.xuggle.xuggler IContainer IContainer$Type IPacket))18 (import '(javax.swing JFrame))20 (import clojure.lang.LazySeq)22 (import '(name.audet.samuel.javacv.jna highgui cv cxcore))24 (import '(name.audet.samuel.javacv CanvasFrame))26 (import '(name.audet.samuel.javacv.jna cxcore$IplImage))28 (import '(name.audet.samuel.javacv.jna highgui$CvCapture$PointerByReference))29 (import '(name.audet.samuel.javacv.jna highgui$CvVideoWriter$PointerByReference))31 ;definitions33 (def -inf Double/NEGATIVE_INFINITY)34 (def inf Double/POSITIVE_INFINITY)36 (use 'clojure.contrib.repl-utils)39 ;minor functions41 (defn converge42 "recursively runs update until prior passes accept, then returns"43 [prior update accept]44 (if (accept prior) prior (recur (update prior) update accept)))46 (defn interval-width [interval] (- (last interval) (first interval)))48 (defn midpoint [interval]49 (let [a (first interval) b (last interval)]50 (if (and (= a -inf) (= b inf)) 051 (if (= a -inf) (midpoint [(- b 200000) b])52 (if (= b inf) (midpoint [a (+ a 200000)])53 (int (/ (+ a b) 2)))))))55 (defn cart256 "calculates the cartesian product in 2 dimensions"57 [point]58 (let [[x y] point] (for [abscissa (range x) ordinate (range y)] [abscissa ordinate])))60 (defn closeCapture61 [capture]62 (highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture)))64 (defn- makePanel [image] (proxy [Panel] [] (paint [g] (.drawImage g image 0 0 nil))))66 (defn screenshot "grab screenshot" []68 (ImageIO/write69 (.createScreenCapture (Robot.) (Rectangle. (.getScreenSize (Toolkit/getDefaultToolkit))))70 "JPG"71 (File. "/home/r/Desktop/screenie.jpg")))73 (defn- readerRecurse74 "calls .readPacket until there's nothing left to do"75 [reader]76 (if (not (nil? (.readPacket reader))) ; here .readPacket actually does the processing as a side-effect.77 nil ; it returns null when it has MORE to process, and signals an error when done...78 (recur reader)))80 (defmacro times81 "perform multiple timed tests on a form"82 [n form]83 `(dotimes [_# ~n] (time ~form)))85 (defmacro me-186 "does macroexpand-1 without having to quote the form"87 [form]88 (list 'macroexpand-1 (list 'quote form)))90 ;Major Functions92 (defmulti display "Creates a JFrame and displays a buffered image" class)94 (defmethod display95 BufferedImage [image]96 (let [panel (makePanel image)97 frame (JFrame. "Oh Yeah!")]98 (.add frame panel)99 (.pack frame)100 (.setVisible frame true )101 (.setSize frame(.getWidth image) (.getHeight image))))103 (defmethod display104 cxcore$IplImage [image]105 ( display (.getBufferedImage image)))107 (defmethod display108 String [image]109 (display (highgui/cvLoadImage image highgui/CV_LOAD_IMAGE_COLOR)))111 (defmethod display112 LazySeq [s]113 (display (first s)))116 (defn convert117 "takes video and converts it to a new type of video"118 [videoInput videoOutput]119 (let [reader (ToolFactory/makeReader videoInput)]120 (doto reader121 (.addListener (ToolFactory/makeWriter videoOutput reader))122 (.addListener (ToolFactory/makeDebugListener (into-array [IMediaDebugListener$Event/META_DATA]))))123 (readerRecurse reader)))127 (defn video-frame128 ":("129 [video frame]130 (lazy-seq131 (try132 (let [capture (highgui/cvCreateFileCapture video)]133 (highgui/cvSetCaptureProperty capture highgui/CV_CAP_PROP_POS_FRAMES frame)134 (println (str "Wanted frame <" frame "> but went to keyFrame " (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_POS_FRAMES)))135 (let [out (highgui/cvQueryFrame capture)136 image (.clone out)]137 (highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture))138 [image]))139 (catch java.lang.NullPointerException _ nil))))144 (defn save-frame145 "takes an opencv image and saves it to disk"146 [frame filename]147 (highgui/cvSaveImage filename frame))150 (defn video-len151 "finds out the real length of a video in log time."152 [video]153 (letfn154 [155 (accept [interval] (= 0 (interval-width interval)))156 (update [interval]157 (let [[a b] interval]158 (if (> (interval-width interval) 2)159 (let [160 middle (midpoint interval)161 frame (first (video-frame video middle))162 ]163 (if (nil? frame) [a middle] [middle b]))164 [a a])))165 ]167 (first (converge [-inf inf] update accept))))168 (def video-len (memoize video-len))172 (defn getData173 "returns a bunch of stuff about a video"174 [video]175 (let176 [capture (highgui/cvCreateFileCapture video)177 info {:frames (video-len video)178 :width (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FRAME_WIDTH)179 :height (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FRAME_HEIGHT)180 :fps (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FPS)181 :codec (highgui/cvGetCaptureProperty capture highgui/CV_CAP_PROP_FOURCC)}]183 (closeCapture capture)184 info))185 (def getData (memoize getData))188 (defn sajitify-linear189 "oh yeah!"190 [video string]191 (let [ capture (highgui/cvCreateFileCapture video)192 frames (:frames (getData video))]193 (dotimes [n frames]194 (highgui/cvSaveImage (str string (format "%06d" n) ".jpg") (highgui/cvQueryFrame capture)))195 (highgui/cvReleaseCapture (highgui$CvCapture$PointerByReference. capture))))197 (defn getFrame198 "gets the frame of a video at the specified time in seconds.199 this works with the simplest interpolation --- just piecewise steps"200 [video time]201 (lazy-seq202 [time (video-frame video (int (* time (:fps (getData video)))))]))204 (defn video-seq-times205 "it's the new and improved version of videoSeq, now using OpenCv.206 we expect a sequence of times in seconds"207 [times video]208 (map #(getFrame video %) times))210 (defn video-seq211 "get's ALL the frames of a video as a lazy sequence of (IplImages)"212 [video]213 (take (:frames (getData video)) (map #(video-frame video %) (iterate inc 0))))215 (defn trans-Writer216 "uses data about the video to make a writer"217 [video fileTarget]218 (let [data (getData video)]219 (highgui/cvCreateVideoWriter fileTarget (highgui/CV_FOURCC "F" "L" "V" "1") (:fps data) (cxcore/cvSize (:width data) (:height data)) 1)))221 (def naturals (iterate inc 0))223 (defn sajitify-seq224 [video string]225 (dorun (map #(highgui/cvSaveImage (str string (format "%06d" %2) ".jpg") (first %1)) (video-seq video) naturals)))