Mercurial > cortex
changeset 216:f5ea63245b3b
completed vision demonstration video and first draft of vision.org
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 10 Feb 2012 11:34:07 -0700 |
parents | f283c62bd212 |
children | 7bf3e3d8fb26 |
files | assets/Models/subtitles/test-render.png assets/Models/subtitles/worm-vision-subtitles.blend images/worm-with-eye.png org/util.org org/vision.org |
diffstat | 5 files changed, 152 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
1.1 Binary file assets/Models/subtitles/test-render.png has changed
2.1 Binary file assets/Models/subtitles/worm-vision-subtitles.blend has changed
3.1 Binary file images/worm-with-eye.png has changed
4.1 --- a/org/util.org Fri Feb 10 02:19:24 2012 -0700 4.2 +++ b/org/util.org Fri Feb 10 11:34:07 2012 -0700 4.3 @@ -403,7 +403,8 @@ 4.4 cannon-ball 4.5 (sphere 0.7 4.6 :material "Common/MatDefs/Misc/Unshaded.j3md" 4.7 - :texture "Textures/PokeCopper.jpg" 4.8 + :color ColorRGBA/White 4.9 + :name "cannonball!" 4.10 :position 4.11 (.add (.getLocation camera) 4.12 (.mult (.getDirection camera) (float 1))) 4.13 @@ -411,7 +412,9 @@ 4.14 (.setLinearVelocity 4.15 (.getControl cannon-ball RigidBodyControl) 4.16 (.mult (.getDirection camera) (float 50))) ;50 4.17 - (add-element game cannon-ball (if node node (.getRootNode game))))))) 4.18 + (add-element game cannon-ball (if node node (.getRootNode 4.19 + game))) 4.20 + cannon-ball)))) 4.21 ([] 4.22 (fire-cannon-ball false))) 4.23
5.1 --- a/org/vision.org Fri Feb 10 02:19:24 2012 -0700 5.2 +++ b/org/vision.org Fri Feb 10 11:34:07 2012 -0700 5.3 @@ -8,8 +8,7 @@ 5.4 #+babel: :mkdirp yes :noweb yes :exports both 5.5 5.6 * Vision 5.7 - 5.8 - 5.9 + 5.10 Vision is one of the most important senses for humans, so I need to 5.11 build a simulated sense of vision for my AI. I will do this with 5.12 simulated eyes. Each eye can be independely moved and should see its 5.13 @@ -143,8 +142,6 @@ 5.14 They can be queried every cycle, but their information may not 5.15 necessairly be different every cycle. 5.16 5.17 - 5.18 - 5.19 * Physical Eyes 5.20 5.21 The vision pipeline described above handles the flow of rendered 5.22 @@ -162,24 +159,6 @@ 5.23 #+begin_src clojure 5.24 (in-ns 'cortex.vision) 5.25 5.26 -(import com.jme3.math.Vector3f) 5.27 - 5.28 -(def blender-rotation-correction 5.29 - (doto (Quaternion.) 5.30 - (.fromRotationMatrix 5.31 - (doto (Matrix3f.) 5.32 - (.setColumn 0 5.33 - (Vector3f. 1 0 0)) 5.34 - (.setColumn 1 5.35 - (Vector3f. 0 -1 0)) 5.36 - (.setColumn 2 5.37 - (Vector3f. 0 0 -1))) 5.38 - 5.39 - (doto (Matrix3f.) 5.40 - (.setColumn 0 5.41 - (Vector3f. 5.42 - 5.43 - 5.44 (defn add-eye! 5.45 "Create a Camera centered on the current position of 'eye which 5.46 follows the closest physical node in 'creature and sends visual 5.47 @@ -197,10 +176,6 @@ 5.48 ;; this part is consistent with using Z in 5.49 ;; blender as the UP vector. 5.50 (.mult rot Vector3f/UNIT_Y)) 5.51 - 5.52 - (println-repl "eye unit-z ->" (.mult rot Vector3f/UNIT_Z)) 5.53 - (println-repl "eye unit-y ->" (.mult rot Vector3f/UNIT_Y)) 5.54 - (println-repl "eye unit-x ->" (.mult rot Vector3f/UNIT_X)) 5.55 (.setFrustumPerspective 5.56 cam 45 (/ (.getWidth cam) (.getHeight cam)) 1 1000) 5.57 (bind-sense target cam) cam)) 5.58 @@ -279,6 +254,7 @@ 5.59 dimansions of the smallest image required to contain all the retinal 5.60 sensor maps. 5.61 5.62 +#+name: retina 5.63 #+begin_src clojure 5.64 (defn retina-sensor-profile 5.65 "Return a map of pixel sensitivity numbers to BufferedImages 5.66 @@ -306,7 +282,7 @@ 5.67 5.68 First off, get the children of the "eyes" empty node to find all the 5.69 eyes the creature has. 5.70 - 5.71 +#+name: eye-node 5.72 #+begin_src clojure 5.73 (defvar 5.74 ^{:arglists '([creature])} 5.75 @@ -318,6 +294,7 @@ 5.76 Then, add the camera created by =(add-eye!)= to the simulation by 5.77 creating a new viewport. 5.78 5.79 +#+name: add-camera 5.80 #+begin_src clojure 5.81 (defn add-camera! 5.82 "Add a camera to the world, calling continuation on every frame 5.83 @@ -343,6 +320,7 @@ 5.84 massive gain in speed. =(vision-kernel)= generates a list of such 5.85 continuation functions, one for each channel of the eye. 5.86 5.87 +#+name: kernel 5.88 #+begin_src clojure 5.89 (in-ns 'cortex.vision) 5.90 5.91 @@ -351,6 +329,21 @@ 5.92 (invoke [this world] (vision-fn world)) 5.93 (applyTo [this args] (apply vision-fn args))) 5.94 5.95 +(defn pixel-sense [sensitivity pixel] 5.96 + (let [s-r (bit-shift-right (bit-and 0xFF0000 sensitivity) 16) 5.97 + s-g (bit-shift-right (bit-and 0x00FF00 sensitivity) 8) 5.98 + s-b (bit-and 0x0000FF sensitivity) 5.99 + 5.100 + p-r (bit-shift-right (bit-and 0xFF0000 pixel) 16) 5.101 + p-g (bit-shift-right (bit-and 0x00FF00 pixel) 8) 5.102 + p-b (bit-and 0x0000FF pixel) 5.103 + 5.104 + total-sensitivity (* 255 (+ s-r s-g s-b))] 5.105 + (float (/ (+ (* s-r p-r) 5.106 + (* s-g p-g) 5.107 + (* s-b p-b)) 5.108 + total-sensitivity)))) 5.109 + 5.110 (defn vision-kernel 5.111 "Returns a list of functions, each of which will return a color 5.112 channel's worth of visual information when called inside a running 5.113 @@ -378,7 +371,7 @@ 5.114 (fn [[key image]] 5.115 (let [whites (white-coordinates image) 5.116 topology (vec (collapse whites)) 5.117 - mask (color-channel-presets key key)] 5.118 + sensitivity (sensitivity-presets key key)] 5.119 (attached-viewport. 5.120 (fn [world] 5.121 (register-eye! world) 5.122 @@ -386,8 +379,9 @@ 5.123 topology 5.124 (vec 5.125 (for [[x y] whites] 5.126 - (bit-and 5.127 - mask (.getRGB @vision-image x y)))))) 5.128 + (pixel-sense 5.129 + sensitivity 5.130 + (.getRGB @vision-image x y)))))) 5.131 register-eye!))) 5.132 retinal-map)))) 5.133 5.134 @@ -398,7 +392,6 @@ 5.135 (runonce 5.136 (fn [world] 5.137 (add-camera! world (.getCamera world) no-op)))) 5.138 - 5.139 #+end_src 5.140 5.141 Note that since each of the functions generated by =(vision-kernel)= 5.142 @@ -419,6 +412,7 @@ 5.143 =(vision-kernel)= to each eye in the creature and gather the results 5.144 into one list of functions. 5.145 5.146 +#+name: main 5.147 #+begin_src clojure 5.148 (defn vision! 5.149 "Returns a function which returns visual sensory data when called 5.150 @@ -436,7 +430,10 @@ 5.151 =(view-sense)= to construct a function that will create a display for 5.152 visual data. 5.153 5.154 +#+name: display 5.155 #+begin_src clojure 5.156 +(in-ns 'cortex.vision) 5.157 + 5.158 (defn view-vision 5.159 "Creates a function which accepts a list of visual sensor-data and 5.160 displays each element of the list to the screen." 5.161 @@ -448,7 +445,7 @@ 5.162 (dorun 5.163 (for [i (range (count coords))] 5.164 (.setRGB image ((coords i) 0) ((coords i) 1) 5.165 - (sensor-data i)))) 5.166 + (gray (int (* 255 (sensor-data i))))))) 5.167 image)))) 5.168 #+end_src 5.169 5.170 @@ -547,10 +544,18 @@ 5.171 5.172 This is the approximation to the human eye described earlier. 5.173 5.174 +#+name: test-2 5.175 #+begin_src clojure 5.176 (in-ns 'cortex.test.vision) 5.177 5.178 -(import com.aurellem.capture.Capture) 5.179 +(defn change-color [obj color] 5.180 + (println-repl obj) 5.181 + (if obj 5.182 + (.setColor (.getMaterial obj) "Color" color))) 5.183 + 5.184 +(defn colored-cannon-ball [color] 5.185 + (comp #(change-color % color) 5.186 + (fire-cannon-ball))) 5.187 5.188 (defn test-worm-vision [] 5.189 (let [the-worm (doto (worm)(body!)) 5.190 @@ -566,12 +571,19 @@ 5.191 :position (Vector3f. 0 -5 0)) 5.192 z-axis 5.193 (box 0.01 0.01 1 :physical? false :color ColorRGBA/Blue 5.194 - :position (Vector3f. 0 -5 0))] 5.195 + :position (Vector3f. 0 -5 0)) 5.196 + timer (RatchetTimer. 60)] 5.197 5.198 (world (nodify [(floor) the-worm x-axis y-axis z-axis me]) 5.199 - standard-debug-controls 5.200 + (assoc standard-debug-controls 5.201 + "key-r" (colored-cannon-ball ColorRGBA/Red) 5.202 + "key-b" (colored-cannon-ball ColorRGBA/Blue) 5.203 + "key-g" (colored-cannon-ball ColorRGBA/Green)) 5.204 (fn [world] 5.205 (light-up-everything world) 5.206 + (speed-up world) 5.207 + (.setTimer world timer) 5.208 + (display-dialated-time world timer) 5.209 ;; add a view from the worm's perspective 5.210 (add-camera! 5.211 world 5.212 @@ -583,9 +595,11 @@ 5.213 (File. "/home/r/proj/cortex/render/worm-vision/worm-view")) 5.214 BufferedImage!)) 5.215 (set-gravity world Vector3f/ZERO) 5.216 - (Capture/captureVideo 5.217 - world 5.218 - (File. "/home/r/proj/cortex/render/worm-vision/main-view"))) 5.219 + (try 5.220 + (Capture/captureVideo 5.221 + world 5.222 + (File. "/home/r/proj/cortex/render/worm-vision/main-view")))) 5.223 + 5.224 (fn [world _ ] 5.225 (.setLocalTranslation me (.getLocation (.getCamera world))) 5.226 (vision-display 5.227 @@ -594,6 +608,69 @@ 5.228 (fix-display world))))) 5.229 #+end_src 5.230 5.231 +** Methods to Generate the Worm Video 5.232 +#+name: magick2 5.233 +#+begin_src clojure 5.234 +(ns cortex.video.magick2 5.235 + (:import java.io.File) 5.236 + (:use clojure.contrib.shell-out)) 5.237 + 5.238 +(defn images [path] 5.239 + (sort (rest (file-seq (File. path))))) 5.240 + 5.241 +(def base "/home/r/proj/cortex/render/worm-vision/") 5.242 + 5.243 +(defn pics [file] 5.244 + (images (str base file))) 5.245 + 5.246 +(defn combine-images [] 5.247 + (let [main-view (pics "main-view") 5.248 + worm-view (pics "worm-view") 5.249 + blue (pics "0") 5.250 + green (pics "1") 5.251 + red (pics "2") 5.252 + gray (pics "3") 5.253 + blender (let [b-pics (pics "blender")] 5.254 + (concat b-pics (repeat 9001 (last b-pics)))) 5.255 + background (repeat 9001 (File. (str base "background.png"))) 5.256 + targets (map 5.257 + #(File. (str base "out/" (format "%07d.png" %))) 5.258 + (range 0 (count main-view)))] 5.259 + (dorun 5.260 + (pmap 5.261 + (comp 5.262 + (fn [[background main-view worm-view red green blue gray blender target]] 5.263 + (println target) 5.264 + (sh "convert" 5.265 + background 5.266 + main-view "-geometry" "+18+17" "-composite" 5.267 + worm-view "-geometry" "+677+17" "-composite" 5.268 + green "-geometry" "+685+430" "-composite" 5.269 + red "-geometry" "+788+430" "-composite" 5.270 + blue "-geometry" "+894+430" "-composite" 5.271 + gray "-geometry" "+1000+430" "-composite" 5.272 + blender "-geometry" "+0+0" "-composite" 5.273 + target)) 5.274 + (fn [& args] (map #(.getCanonicalPath %) args))) 5.275 + background main-view worm-view red green blue gray blender targets)))) 5.276 +#+end_src 5.277 + 5.278 +#+begin_src sh :results silent 5.279 +cd /home/r/proj/cortex/render/worm-vision 5.280 +ffmpeg -r 25 -b 9001k -i out/%07d.png -vcodec libtheora worm-vision.ogg 5.281 +#+end_src 5.282 + 5.283 +* Demonstration of Vision 5.284 +#+begin_html 5.285 +<div class="figure"> 5.286 +<video controls="controls" width="755"> 5.287 + <source src="../video/worm-vision.ogg" type="video/ogg" 5.288 + preload="none" poster="../images/aurellem-1280x480.png" /> 5.289 +</video> 5.290 +<p>Simulated Vision in a Virtual Environment</p> 5.291 +</div> 5.292 +#+end_html 5.293 + 5.294 * Headers 5.295 5.296 #+name: vision-header 5.297 @@ -602,7 +679,7 @@ 5.298 "Simulate the sense of vision in jMonkeyEngine3. Enables multiple 5.299 eyes from different positions to observe the same world, and pass 5.300 the observed data to any arbitray function. Automatically reads 5.301 - eye-nodes from specially prepared blender files and instanttiates 5.302 + eye-nodes from specially prepared blender files and instantiates 5.303 them in the world as actual eyes." 5.304 {:author "Robert McIntyre"} 5.305 (:use (cortex world sense util)) 5.306 @@ -612,7 +689,7 @@ 5.307 (:import java.nio.ByteBuffer) 5.308 (:import java.awt.image.BufferedImage) 5.309 (:import (com.jme3.renderer ViewPort Camera)) 5.310 - (:import com.jme3.math.ColorRGBA) 5.311 + (:import (com.jme3.math ColorRGBA Vector3f Matrix3f)) 5.312 (:import com.jme3.renderer.Renderer) 5.313 (:import com.jme3.app.Application) 5.314 (:import com.jme3.texture.FrameBuffer) 5.315 @@ -632,21 +709,46 @@ 5.316 (:import com.jme3.math.ColorRGBA) 5.317 (:import com.jme3.scene.Node) 5.318 (:import com.jme3.math.Vector3f) 5.319 - (:import java.io.File)) 5.320 + (:import java.io.File) 5.321 + (:import (com.aurellem.capture Capture RatchetTimer))) 5.322 #+end_src 5.323 5.324 +* Onward! 5.325 + - As a neat bonus, this idea behind simulated vision also enables one 5.326 + to [[../../cortex/html/capture-video.html][capture live video feeds from jMonkeyEngine]]. 5.327 + - Now that we have vision, it's time to tackle [[./hearing.org][hearing]]. 5.328 5.329 - 5.330 -- As a neat bonus, this idea behind simulated vision also enables one 5.331 - to [[../../cortex/html/capture-video.html][capture live video feeds from jMonkeyEngine]]. 5.332 +* Source Listing 5.333 + - [[../src/cortex/vision.clj][cortex.vision]] 5.334 + - [[../src/cortex/test/vision.clj][cortex.test.vision]] 5.335 + - [[../src/cortex/video/magick2.clj][cortex.video.magick2]] 5.336 + - [[../assets/Models/subtitles/worm-vision-subtitles.blend][worm-vision-subtitles.blend]] 5.337 +#+html: <ul> <li> <a href="../org/sense.org">This org file</a> </li> </ul> 5.338 + - [[http://hg.bortreb.com ][source-repository]] 5.339 + 5.340 5.341 5.342 * COMMENT Generate Source 5.343 #+begin_src clojure :tangle ../src/cortex/vision.clj 5.344 -<<eyes>> 5.345 +<<vision-header>> 5.346 +<<pipeline-1>> 5.347 +<<pipeline-2>> 5.348 +<<retina>> 5.349 +<<add-eye>> 5.350 +<<sensitivity>> 5.351 +<<eye-node>> 5.352 +<<add-camera>> 5.353 +<<kernel>> 5.354 +<<main>> 5.355 +<<display>> 5.356 #+end_src 5.357 5.358 #+begin_src clojure :tangle ../src/cortex/test/vision.clj 5.359 <<test-header>> 5.360 <<test-1>> 5.361 +<<test-2>> 5.362 #+end_src 5.363 + 5.364 +#+begin_src clojure :tangle ../src/cortex/video/magick2.clj 5.365 +<<magick2>> 5.366 +#+end_src