comparison src/laser/rasterize.clj @ 16:52f544d05414

I think I've made it worse....
author Robert McIntyre <rlm@mit.edu>
date Sun, 29 Aug 2010 23:40:39 -0400
parents 8ad629298649
children 962e223bab0d
comparison
equal deleted inserted replaced
15:8ad629298649 16:52f544d05414
3 image-utils 3 image-utils
4 map-utils] 4 map-utils]
5 [clojure.contrib 5 [clojure.contrib
6 [str-utils :only [str-join re-gsub]] 6 [str-utils :only [str-join re-gsub]]
7 [seq :only [indexed]] 7 [seq :only [indexed]]
8 [math]]) 8 [math]
9 [def]
10 ])
9 (:import [ij ImagePlus IJ])) 11 (:import [ij ImagePlus IJ]))
10 12
11 ;(import '(java.io File)) 13 ;(import '(java.io File))
12 ;(import '(org.apache.commons.io FileUtils)) 14 ;(import '(org.apache.commons.io FileUtils))
13 ;(import '(javax.imageio ImageIO) ) 15 ;(import '(javax.imageio ImageIO) )
15 17
16 (set! *print-length* 20) 18 (set! *print-length* 20)
17 (def feed 120) 19 (def feed 120)
18 (def dpi [500, 500]) 20 (def dpi [500, 500])
19 21
22 (def paramaters {:x-dpi 500 :y-dpi 500 :margin 0 :x-offset 0 :y-offset 0})
20 23
21 ;;; this process is divided into two tasks, 24 ;;; this process is divided into two tasks,
22 ;;; creating the raster g-code, which sweeps back and forth 25 ;;; creating the raster g-code, which sweeps back and forth
23 ;;; and creating the gmask, which turns the laser on and off. 26 ;;; and creating the gmask, which turns the laser on and off.
24 27
25 28
26 ;;; we'll be using frame-hashes, which represent picutres as 29 ;;; we'll be using frame-hashes, which represent picutres as
27 ;;; a 3D vector field over 2D space, with the vectors representing 30 ;;; a 3D vector field over 2D space, with the vectors representing
28 ;;; the rgb values at that particulat point. 31 ;;; the rgb values at that particular point.
29 32
30 (defn select-row 33 (defn select-row
31 "returns a frame hash that is just a single line at the chosen y" 34 "returns a frame hash that is just a single line at the chosen y"
32 [y window] 35 [y window]
33 (filter-keys (comp (partial = y) last) window)) 36 (reduce
37 (fn [old-map number]
38 (let [pixel (get window [number y] nil)]
39 (if-not (nil? pixel)
40 (into old-map {[number y] pixel})
41 old-map)))
42 {}
43 (range (width window))))
34 44
35 (defn make-rows [pic] 45 (defn make-rows [pic]
36 (map (partial sort #(< (first %1) (first %2))) 46 (map (partial sort #(< (first %1) (first %2)))
37 (partition-by last 47 (partition-by last
38 (sort (fn [[x1 y1][x2 y2]] (> y2 y1)) 48 (sort (fn [[x1 y1][x2 y2]] (> y2 y1))
39 (map first (filter-vals (partial = black) pic)))))) 49 (map first (filter-vals (partial = black) pic))))))
40 50
41
42 ;;; generate rastering g-code 51 ;;; generate rastering g-code
43 52
44 (defn raster-preamble [] 53 (defn raster-preamble []
45 (str-join \newline 54 (str-join \newline ["M63 P0\nG61" (str "F" feed) "M101" "M3 S1\n"]))
46 ["M63 P0\nG61"
47 (str "F" feed)
48 "M101"
49 "M3 S1\n"]))
50 55
51 (defn raster-epilogue [] 56 (defn raster-epilogue []
52 (str-join \newline 57 (str-join \newline ["M63 P0" "M5" "M2\n"]))
53 ["M63 P0" 58
54 "M5" 59 (defn raster-comment
55 "M2\n"])) 60 "wrap a statement in PARENTHENSIS to make it a comment in gcode.
56 61 parenthesis themselves aren't allowed in comments.
57 (defn raster-comment [string] 62 Oh the humanity!!"
63 [string]
58 (str "(" (re-gsub #"[()]" "" string) ")")) 64 (str "(" (re-gsub #"[()]" "" string) ")"))
59 65
60 66 (defn rows
61 ;this is a sequence of rows 67 "creates a sequence of one dimensional vector fields which
62 68 represent the rows of a picture"
63 ;(defn span [row] 69 [pic]
64 ; (let [sorted-row (sort #(< (first %1) (first %2)) row)] 70 (let [non-empty-rows (apply sorted-set (map (comp last first) pic))]
65 ; (vector (first sorted-row) (last sorted-row)))) 71 (pmap (fn [n] (select-row n pic)) non-empty-rows)))
66 72
67
68
69 (defn row->gcode [[x-dpi y-dpi] forward? row]
70 73
71 (let [[x1 y1] (if forward? (last row) (first row)) 74
72 [x2 y2] (if forward? (first row) (last row))] 75
76
77 (defn row->gcode [{:keys [x-dpi y-dpi margin x-offset y-offset]} row]
78 (let [pixels (keys row)
79 x2 0
80 [_ y2] (first pixels)
81 [_ y1] (first pixels)
82 x1 533]
83
84 ;(let [ordered-row
85 ; (sort-map-by (fn [[x1 _] [x2 _]] (> x2 x1)) row)]
73 86
74 87 (let [;[x1 y1] (last (keys ordered-row))
75 ; (let [[x1 y1] (first row) 88 ;[x2 y2] (first (keys ordered-row))
76 ; [x2 y2] (last row) 89 [x1 y1 x2 y2] (if (odd? y1) [x2 y2 x1 y1] [x1 y1 x2 y2])]
77 ; x2 (+ x2 (* x-dpi 0.318))] 90
78 91 (str (format "G0 X%.3f Y%.3f\n"
79 92 (float (* x1 (/ x-dpi)))
80 ; (println x2) 93 (float (* y1 (/ y-dpi))))
81 (str (format "G0 X%.3f Y%.3f\n" 94
82 (float (* x1 (/ x-dpi))) 95 (format "G1 X%.3f Y%.3f\n"
83 (float (* y1 (/ y-dpi)))) 96 (float (* x2 (/ x-dpi)))
84 97 (float (* y2 (/ y-dpi))))))))
85 (format "G1 X%.3f Y%.3f\n" 98
86 (float (* x2 (/ x-dpi))) 99
87 (float (* y2 (/ y-dpi))))))) 100 (defn pic->gcode [paramaters pic]
88 101 (reduce (fn [gcode current-height]
102 (let [current-row (select-row current-height pic)]
103 (if-not (empty? current-row)
104 (let [new-code (row->gcode paramaters current-row)]
105 (println new-code)
106 (str gcode new-code))
107 gcode)))
108 ""
109 (range (height pic))))
110
111
112 ;(defn pic->gcode [paramaters pic]
113
89 114
90 (defn generate-gcode [pic] 115 (defn generate-gcode [pic]
91 (str (raster-preamble) 116 (str (raster-preamble)
92 (str-join "" 117 (row->gcode paramaters pic)
93 (map 118 (raster-epilogue)))
94 (fn [[index row]]
95 (row->gcode dpi (even? index) row))
96 (indexed (make-rows pic))))
97 (raster-epilogue)))
98 119
99 120
100 121
101 122
102 123
184 pic) 205 pic)
185 206
186 (defn update-state [] 207 (defn update-state []
187 (def sing "/home/r/kevin/sing.png") 208 (def sing "/home/r/kevin/sing.png")
188 (def pic (frame-hash (ImagePlus. sing))) 209 (def pic (frame-hash (ImagePlus. sing)))
189 (def pic (b&w pic))) 210 (def pic (b&w pic))
190 211 (def pic (filter-vals (partial = black) pic)))
191 (defn compare-gen-fn [n f cmp] 212
213 (defn compare-gen-fn
214 ([n f cmp]
192 (let [theirs (re-split #"\n" (slurp cmp)) 215 (let [theirs (re-split #"\n" (slurp cmp))
193 ours (re-split #"\n" (f pic))] 216 ours (re-split #"\n" (f pic))]
194 (println (format "%1$-25s%2$s" "OURS" "THEIRS")) 217 (println (format "%1$-25s%2$s" "OURS" "THEIRS"))
195 (println "_______________________________________") 218 (println "_______________________________________")
196 (dorun (map (fn [[us them]] (println 219 (dorun (map (fn [[us them]] (println
197 (format "%1$-25s%2$s" us them))) 220 (format "%1$-25s%2$s" us them)))
198 (take n (partition 2 (interleave ours theirs))))))) 221 (take n (partition 2 (interleave ours theirs))))))))
199 222
200 (defn compare-gcode [n] 223 (defn compare-gcode
201 (compare-gen-fn n generate-gcode "/home/r/kevin/reference.ngc")) 224 ([] (compare-gcode 25))
202 (defn compare-gmask [n] 225 ([n] (compare-gen-fn n generate-gcode "/home/r/kevin/reference.ngc")))
203 (compare-gen-fn n generate-gmask "/home/r/kevin/reference.gmask")) 226
227 (defn compare-gmask
228 ([] compare-gmask 25)
229 ([n] (compare-gen-fn n generate-gmask "/home/r/kevin/reference.gmask")))
204 230
205 231
206 232
207 233
208 234