kxygk / buubletea

This is a basic example for working in Clojure with JavaFX, OpenCV and simple plotting
https://geokon-gh.github.io/buubletea/
0 stars 0 forks source link

App Review #1

Open hellonico opened 6 years ago

hellonico commented 6 years ago

I can the application to load ...

What is the left-est picture showing in each of the todo -item ?

screen shot 2018-06-07 at 14 06 15
kxygk commented 6 years ago

Thanks for trying it out :)

It's just supposed to grab a snapshot from the camera. The first 4 functions get the snapshot and transform it into a JavaFX Node. And then I'm displaying that as a still image

So the GUI is running but you're not seeing any images?

hellonico commented 6 years ago

So, yes you are correct in the comments in your code. The mat is changed inplace.

So when you take a picture from the cam, and the other ones, you need to clone the image first.

         first-image-edges (-> first-image ; THIS CHANGES THE MAT INPLACE!
+                              oc/clone ; THIS prevents it
                               (oc/cvt-color! oc/COLOR_RGB2GRAY)
                               (oc/canny! 300.0 100.0 3 true)
                               (oc/bitwise-not!)
                               (oc/cvt-color! oc/COLOR_GRAY2RGB))

And then you can simply reuse the make-jfx-image-from-mat

[:image (make-jfx-image-from-mat first-image)]

I quickly added those changes: diff.txt

screen shot 2018-06-07 at 17 10 05
kxygk commented 6 years ago

Thank you so much for the feedback. I really appreciate it. I guess I might be missing something b/c at first blush it looks like a lot of extra copying

Looking at for instance my version of the add-item event handler:

(defmethod handle-event :add-item
  [state {:keys [fn-fx/includes webcam-params]}]
  (println (:current-webcam-params state))
  (let [webcam-params (:current-webcam-params state)
        width (-> webcam-params :video :width)
        height (-> webcam-params :video :height)
        snapshot (webcam-image webcam-params)
        snapshot-buffer (get-mat-byte-buffer snapshot)
        snapshot-edges (-> snapshot
                           (oc/cvt-color! oc/COLOR_RGB2GRAY)
                           (oc/canny! 300.0 100.0 3 true)
                           (oc/bitwise-not!)
                           (oc/cvt-color! oc/COLOR_GRAY2RGB))]
    (update-in state [:todos] conj {:done? false
                                    :text (get-in includes [::new-item :text])
                                    :webcam-params webcam-params
                                    :image (make-jfx-image-from-byte-buffer snapshot-buffer width height)
                                    :histogram (image-to-histogram snapshot-buffer 256 width height)
                                    :image-edges (make-jfx-image-from-mat snapshot-edges)})))

I'm getting the webcam frame and putting it into snapshot. Then I'm copying out the buffer into a byte array - so it's sorta acting like a oc/clone here b/c I no longer care about the RGB Mat. Since I no longer need it, I reuse it in-place for the edge-detection.

And the snapshot-buffer I extracted/copied out of the RGB Mat I also reuse both for displaying the RBG image as well as building the histogram without any extra copying.

The way you fixed it looks like it ends up copying the matrix 2 extra times and copying the buffer out 2 times.

Again, since it's not working for you, I must be missing something about origami. Maybe the get-mat-byte-buffer which uses the Mat's get function isn't actually making a copy? ie. (.get mat 0 0 image-buffer)

Again, thanks for looking into to this :)

hellonico commented 6 years ago

Yes, you can forget the diff.

You only need one clone in the pipeline. So only one copy.

kxygk commented 6 years ago

Great! Just so I understand, why does the pipeline need a clone? It can't modify the original Mat from the webcam?