annotate src/laser/rasterize.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 6bed8ceb51a9
children
rev   line source
rlm@15 1 (ns laser.rasterize
rlm@15 2 (:use [rlm
rlm@15 3 image-utils
rlm@15 4 map-utils]
rlm@15 5 [clojure.contrib
rlm@19 6 [str-utils :only [str-join re-gsub re-split]]
rlm@15 7 [seq :only [indexed]]
rlm@19 8 [math]])
rlm@15 9 (:import [ij ImagePlus IJ]))
rlm@0 10
rlm@15 11 ;(import '(java.io File))
rlm@15 12 ;(import '(org.apache.commons.io FileUtils))
rlm@15 13 ;(import '(javax.imageio ImageIO) )
rlm@0 14
rlm@0 15
rlm@15 16 (set! *print-length* 20)
rlm@1 17 (def feed 120)
rlm@1 18 (def dpi [500, 500])
rlm@21 19 (def paramaters {:x-dpi 500 :y-dpi 500 :margin 0.501 :x-offset 1.001 :y-offset 1})
rlm@8 20
rlm@15 21 ;;; this process is divided into two tasks,
rlm@15 22 ;;; creating the raster g-code, which sweeps back and forth
rlm@15 23 ;;; and creating the gmask, which turns the laser on and off.
rlm@1 24
rlm@1 25
rlm@15 26 ;;; we'll be using frame-hashes, which represent picutres as
rlm@15 27 ;;; a 3D vector field over 2D space, with the vectors representing
rlm@19 28 ;;; the rgb values at that particulat point.
rlm@2 29
rlm@15 30 (defn select-row
rlm@15 31 "returns a frame hash that is just a single line at the chosen y"
rlm@15 32 [y window]
rlm@19 33 (filter-keys (comp (partial = y) last) window))
rlm@1 34
rlm@15 35 (defn make-rows [pic]
rlm@15 36 (map (partial sort #(< (first %1) (first %2)))
rlm@15 37 (partition-by last
rlm@15 38 (sort (fn [[x1 y1][x2 y2]] (> y2 y1))
rlm@15 39 (map first (filter-vals (partial = black) pic))))))
rlm@1 40
rlm@19 41
rlm@15 42 ;;; generate rastering g-code
rlm@1 43
rlm@3 44 (defn raster-preamble []
rlm@19 45 (str-join \newline
rlm@19 46 ["M63 P0\nG61"
rlm@19 47 (str "F" feed)
rlm@19 48 "M101"
rlm@19 49 "M3 S1\n"]))
rlm@3 50
rlm@4 51 (defn raster-epilogue []
rlm@19 52 (str-join \newline
rlm@19 53 ["M63 P0"
rlm@19 54 "M5"
rlm@19 55 "M2\n"]))
rlm@3 56
rlm@19 57 (defn raster-comment [string]
rlm@4 58 (str "(" (re-gsub #"[()]" "" string) ")"))
rlm@1 59
rlm@19 60
rlm@19 61 ;this is a sequence of rows
rlm@19 62
rlm@19 63 ;(defn span [row]
rlm@19 64 ; (let [sorted-row (sort #(< (first %1) (first %2)) row)]
rlm@19 65 ; (vector (first sorted-row) (last sorted-row))))
rlm@19 66
rlm@19 67
rlm@20 68 (comment
rlm@19 69
rlm@20 70 (import 'org.im4java.core.ConvertCmd)
rlm@20 71 (import 'org.im4java.core.IMOperation)
rlm@20 72 (import 'org.im4java.core.Stream2BufferedImage)
rlm@21 73
rlm@20 74 (def target (.getBufferedImage (ImagePlus. sing)))
rlm@21 75 (def shiv (IMOperation.))
rlm@21 76 (.addImage shiv)
rlm@21 77 (.addImage shiv (into-array String ["png:-"]))
rlm@21 78 (def conv-shiv (ConvertCmd.))
rlm@21 79 (def s2b (Stream2BufferedImage.))
rlm@21 80 (.setOutputConsumer conv-shiv s2b)
rlm@21 81 (.run conv-shiv shiv (into-array Object [target]))
rlm@21 82 (def result (.getImage s2b ))
rlm@20 83
rlm@20 84 )
rlm@20 85
rlm@21 86 (defn mirror
rlm@21 87 "ImagePlus to ImagePlus via imageMagick through im4java!"
rlm@21 88 [#^ImagePlus img]
rlm@20 89 (let [title (.getTitle img)
rlm@20 90 target (.getBufferedImage img)
rlm@20 91 s2b (Stream2BufferedImage.)
rlm@20 92 shiv (doto (IMOperation.)
rlm@20 93 ;(.blur 2.0)
rlm@20 94 (.flip)
rlm@20 95 (.addImage)
rlm@20 96 (.addImage (into-array String ["png:-"])))
rlm@20 97 conv-shiv (doto (ConvertCmd.)
rlm@20 98 (.setOutputConsumer s2b))]
rlm@20 99
rlm@20 100 (.run conv-shiv shiv (into-array Object [target]))
rlm@20 101 (ImagePlus. title (.getImage s2b))))
rlm@20 102
rlm@20 103
rlm@20 104
rlm@19 105 (defn row->gcode [{:keys [x-dpi y-dpi margin x-offset y-offset]} forward? row]
rlm@16 106
rlm@19 107 (let [[x1 y1] (if forward? (last row) (first row))
rlm@19 108 [x2 y2] (if forward? (first row) (last row))]
rlm@5 109
rlm@19 110 (let [x1 (* x1 (/ x-dpi))
rlm@19 111 x2 (* x2 (/ x-dpi))
rlm@19 112 y1 (* y1 (/ y-dpi))
rlm@20 113 y2 (* y2 (/ y-dpi))]
rlm@7 114
rlm@19 115 (let [x1 (+ x1 x-offset)
rlm@19 116 x2 (+ x2 x-offset)
rlm@19 117 y1 (+ y1 y-offset)
rlm@19 118 y2 (+ y2 y-offset)]
rlm@20 119
rlm@21 120 (let [margin (if forward? margin (- margin))]
rlm@21 121
rlm@21 122 (let [x1 (+ x1 margin)
rlm@21 123 x2 (- x2 margin)]
rlm@21 124
rlm@20 125
rlm@19 126
rlm@16 127 (str (format "G0 X%.3f Y%.3f\n"
rlm@19 128 (float x1 )
rlm@19 129 (float y1))
rlm@16 130
rlm@16 131 (format "G1 X%.3f Y%.3f\n"
rlm@19 132 (float x2)
rlm@21 133 (float y2)))))))))
rlm@14 134
rlm@15 135 (defn generate-gcode [pic]
rlm@15 136 (str (raster-preamble)
rlm@19 137 (str-join ""
rlm@19 138 (map
rlm@19 139 (fn [[index row]]
rlm@19 140 (row->gcode paramaters (even? index) row))
rlm@19 141 (indexed (make-rows pic))))
rlm@19 142 (raster-epilogue)))
rlm@15 143
rlm@15 144
rlm@15 145
rlm@15 146
rlm@15 147
rlm@15 148
rlm@15 149
rlm@15 150
rlm@15 151
rlm@15 152
rlm@15 153
rlm@15 154
rlm@15 155
rlm@15 156
rlm@15 157
rlm@15 158
rlm@15 159
rlm@15 160
rlm@15 161
rlm@7 162 (defn gather-row [row]
rlm@7 163 (let [base [[(first (first row)) (first (first row))]]]
rlm@7 164 ; (println base)
rlm@7 165 (reduce
rlm@7 166 (fn colapse [collection new-n]
rlm@7 167
rlm@7 168 (let [collection (apply vector collection)
rlm@7 169 prevoius (last (last collection))
rlm@7 170 range-start (first (last collection))]
rlm@7 171 ; (println new-n)
rlm@7 172 ; (println prevoius)
rlm@7 173 ; (println range-start)
rlm@7 174 (if (<= new-n (+ prevoius 1))
rlm@11 175 (do ;(println "join")
rlm@7 176 ;(println (butlast collection))
rlm@11 177 (conj (apply vector (butlast collection))
rlm@11 178 (vector range-start new-n)))
rlm@11 179 (conj collection (vector new-n new-n)))))
rlm@7 180
rlm@7 181 base
rlm@11 182 (map first row))))
rlm@11 183
rlm@7 184
rlm@7 185
rlm@7 186
rlm@21 187 (defn row->gmask [{:keys [x-dpi y-dpi margin x-offset y-offset]} forward? row]
rlm@11 188 (let [start (float (* (/ x-dpi) (first (first
rlm@11 189 (if forward?
rlm@21 190 (reverse row) row)))))
rlm@21 191 start (+ start x-offset)
rlm@21 192 ]
rlm@11 193 (let [preamble (if-not forward?
rlm@7 194 (format "0 0 0 %.3f\n" start)
rlm@11 195 (format "0 0 1 %.3f\n" start))
rlm@7 196 body
rlm@11 197 (for [[x y]
rlm@11 198 (if forward?
rlm@11 199 (reverse (gather-row row))
rlm@11 200 (gather-row row))]
rlm@7 201 (let [x (float (* x (/ x-dpi)))
rlm@21 202 y (float (* y (/ x-dpi)))
rlm@21 203 x (+ x x-offset)
rlm@21 204 y (+ y y-offset)
rlm@21 205
rlm@21 206
rlm@21 207
rlm@21 208
rlm@21 209 ]
rlm@21 210
rlm@21 211
rlm@11 212 (if-not forward?
rlm@7 213 (str (format "0 0 1 %.3f\n" x)
rlm@7 214 (format "0 1 1 %.3f\n" y))
rlm@7 215
rlm@11 216 (str (format "0 0 0 %.3f\n" y)
rlm@11 217 (format "0 1 0 %.3f\n" x)))))]
rlm@7 218
rlm@7 219 (str preamble (str-join "" body)))))
rlm@7 220
rlm@7 221
rlm@7 222 (defn generate-gmask [pic]
rlm@7 223 (str "1 0 0 0\n"
rlm@8 224 (str-join "" (map (fn [[index row]]
rlm@21 225 (row->gmask paramaters (even? index) row))
rlm@8 226 (indexed (make-rows pic))))))
rlm@8 227
rlm@11 228
rlm@11 229
rlm@8 230
rlm@8 231 ;;;; testing
rlm@8 232
rlm@15 233 (defn generate-files [pic]
rlm@15 234 (println "made-image")
rlm@15 235 (spit "/home/r/kevin/out.ngc" (generate-gcode pic))
rlm@15 236 (println "/home/r/kevin/out.ngc")
rlm@15 237 (spit "/home/r/kevin/out.gmask" (generate-gmask pic))
rlm@15 238 (println "/home/r/kevin/out.gmask")
rlm@15 239 pic)
rlm@8 240
rlm@15 241 (defn update-state []
rlm@15 242 (def sing "/home/r/kevin/sing.png")
rlm@20 243 (def pic (frame-hash (mirror (ImagePlus. sing))))
rlm@19 244 (def pic (b&w pic)))
rlm@8 245
rlm@19 246 (defn compare-gen-fn [n f cmp]
rlm@15 247 (let [theirs (re-split #"\n" (slurp cmp))
rlm@15 248 ours (re-split #"\n" (f pic))]
rlm@15 249 (println (format "%1$-25s%2$s" "OURS" "THEIRS"))
rlm@15 250 (println "_______________________________________")
rlm@15 251 (dorun (map (fn [[us them]] (println
rlm@15 252 (format "%1$-25s%2$s" us them)))
rlm@19 253 (take n (partition 2 (interleave ours theirs)))))))
rlm@8 254
rlm@19 255 (defn compare-gcode [n]
rlm@19 256 (compare-gen-fn n generate-gcode "/home/r/kevin/reference.ngc"))
rlm@19 257 (defn compare-gmask [n]
rlm@19 258 (compare-gen-fn n generate-gmask "/home/r/kevin/reference.gmask"))
rlm@15 259
rlm@8 260
rlm@8 261
rlm@8 262
rlm@8 263