Pregunta

Let's assume I'd like to wright an ocr algorithm. Therefore I want to create a binary image. Using clojure and quil I came up with:

(defn setup []

  (load-pixels)

  (let [pxls (pixels)
             ]
    (letfn [(pxl-over-threshold? [idx] (if (> (red (aget pxls idx)) 128) true false))
            ]
           (time (dotimes [idx 25500] (aset pxls idx (color (rem idx 255)))))

           (time (dotimes [idx 25500] (if (pxl-over-threshold? idx)
                                          (aset pxls idx (color 255))
                                          (aset pxls idx (color 0)))))))
  (update-pixels))

(defn draw [])

(defsketch example
  :title "image demo"
  :setup setup
  :draw draw
  :size [255 100]
  :renderer :p2d)

;"Elapsed time: 1570.58932 msecs"
;"Elapsed time: 2781.334345 msecs" 

The code generates a grayscale and afterwards iterates over all pixels to set them black or white. It performs the requested behavior, but takes about 4.3 sec to get there (1.3 dual core). I don't have a reference to put the 4.3 sec in context. But thinking of processing a larger image, this must become incredibly slow.

Am I doing something terribly wrong or is there a way to fasten up things? Is the combination of clojure and quil even capable of doing pixel transformations faster or should I choose a different language/environment?

Please also let me know if I'm doing something weird in the code. I'm still new to clojure.

Thanks in advance.

¿Fue útil?

Solución

The timings you've taken aren't particularly meaningful because the code isn't warm yet. You need to "warm up" the code so that the JVM will JIT-compile it, and that's when you should start seeing good speed. You should look at How to benchmark functions in Clojure? (You should use Criterium.)

As for your code, you're using arrays, so that should give you good performance. Style-wise, the two hanging ] you have are really weird. Maybe that's just a formatting error? It's usually good to eliminate as much duplicate code as possible, so I'd also change this

(if (pxl-over-threshold? idx)
  (aset pxls idx (color 255))
  (aset pxls idx (color 0)))

to this

(aset pxls idx (color (if (pxl-over-threshold? idx) 255 0)))

If you feel looks too confusing/complex (I'm kind of right on the edge as to whether I'd consider that too hard to read or not), you could alternatively write it either of these ways instead:

(let [c (if (pxl-over-threshold? idx) 255 0)]
  (aset pxls idx (color c)))

(->> (if (pxl-over-threshold? idx) 255 0) color (aset pxls idx))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top