diff --git a/contrib/clojure-package/examples/gan/.gitignore b/contrib/clojure-package/examples/gan/.gitignore index c53038ec0e3d..ea8013148d11 100644 --- a/contrib/clojure-package/examples/gan/.gitignore +++ b/contrib/clojure-package/examples/gan/.gitignore @@ -9,3 +9,4 @@ pom.xml.asc /.nrepl-port .hgignore .hg/ +results \ No newline at end of file diff --git a/contrib/clojure-package/examples/gan/project.clj b/contrib/clojure-package/examples/gan/project.clj index a326f7a5605f..410568d164e1 100644 --- a/contrib/clojure-package/examples/gan/project.clj +++ b/contrib/clojure-package/examples/gan/project.clj @@ -15,11 +15,12 @@ ;; limitations under the License. ;; -(defproject gan "0.1.0-SNAPSHOT" +(defproject gan-origami "0.1.0-SNAPSHOT" :description "GAN MNIST with MXNet" :plugins [[lein-cljfmt "0.5.7"]] + :repositories [["vendredi" {:url "https://repository.hellonico.info/repository/hellonico/"}]] :dependencies [[org.clojure/clojure "1.9.0"] [org.apache.mxnet.contrib.clojure/clojure-mxnet "1.5.0-SNAPSHOT"] - [org.openpnp/opencv "3.4.2-1"] + [origami "4.0.0-2"] ] - :main gan.gan-mnist) + :main gan.gan-mnist) \ No newline at end of file diff --git a/contrib/clojure-package/examples/gan/src/gan/viz.clj b/contrib/clojure-package/examples/gan/src/gan/viz.clj index 67f78806de66..08da53cb2382 100644 --- a/contrib/clojure-package/examples/gan/src/gan/viz.clj +++ b/contrib/clojure-package/examples/gan/src/gan/viz.clj @@ -18,14 +18,9 @@ (ns gan.viz (:require [org.apache.clojure-mxnet.ndarray :as ndarray] [org.apache.clojure-mxnet.shape :as mx-shape] - [org.apache.clojure-mxnet.io :as mx-io]) - (:import (nu.pattern OpenCV) - (org.opencv.core Core CvType Mat Size) - (org.opencv.imgproc Imgproc) - (org.opencv.imgcodecs Imgcodecs))) - -;;; Viz stuff -(OpenCV/loadShared) + [org.apache.clojure-mxnet.io :as mx-io] + [opencv4.utils :as cvu] + [opencv4.core :as cv :refer [CV_8UC1 new-matofbyte flip! imwrite new-size hconcat! vconcat! new-mat merge!]])) (defn clip [x] (->> x @@ -37,29 +32,11 @@ (mapv #(.byteValue %)))) (defn get-img [raw-data channels height width flip] - (let [totals (* height width) - img (if (> channels 1) - ;; rgb image - (let [[ra ga ba] (byte-array (partition totals raw-data)) - rr (new Mat height width (CvType/CV_8U)) - gg (new Mat height width (CvType/CV_8U)) - bb (new Mat height width (CvType/CV_8U)) - result (new Mat)] - (.put rr (int 0) (int 0) ra) - (.put gg (int 0) (int 0) ga) - (.put bb (int 0) (int 0) ba) - (Core/merge (java.util.ArrayList. [bb gg rr]) result) - result) + (let [img (if (> channels 1) + (throw (Exception. "Image with 3 channels (RGB) not supported")) ;; gray image - (let [result (new Mat height width (CvType/CV_8U)) - _ (.put result (int 0) (int 0) (byte-array raw-data))] - result))] - (do - (if flip - (let [result (new Mat) - _ (Core/flip img result (int 0))] - result) - img)))) + (cv/>> (new-mat height width CV_8UC1) (byte-array raw-data)))] + (if flip (flip! img 0) img))) (defn im-sav [{:keys [title output-path x flip] :or {flip false} :as g-mod}] @@ -73,15 +50,10 @@ line-arrs (into [] (partition (* col c totals) raw-data)) line-mats (mapv (fn [line] (let [img-arr (into [] (partition (* c totals) line)) - col-mats (new Mat) - src (mapv (fn [arr] (get-img (into [] arr) c h w flip)) img-arr) - _ (Core/hconcat (java.util.ArrayList. src) col-mats)] - col-mats)) - line-arrs) - result (new Mat) - resized-img (new Mat) - _ (Core/vconcat (java.util.ArrayList. line-mats) result)] - (do - (Imgproc/resize result resized-img (new Size (* (.width result) 1.5) (* (.height result) 1.5))) - (Imgcodecs/imwrite (str output-path title ".jpg") resized-img) - (Thread/sleep 1000)))) + src (mapv (fn [arr] (get-img (into [] arr) c h w flip)) img-arr)] + (hconcat! src))) + line-arrs)] + (-> line-mats + (vconcat!) + (cvu/resize-by 1.5) + (imwrite (str output-path title ".jpg"))))) \ No newline at end of file diff --git a/contrib/clojure-package/examples/infer/objectdetector/.gitignore b/contrib/clojure-package/examples/infer/objectdetector/.gitignore index 35491f1a084a..a1f0468035fe 100644 --- a/contrib/clojure-package/examples/infer/objectdetector/.gitignore +++ b/contrib/clojure-package/examples/infer/objectdetector/.gitignore @@ -10,3 +10,4 @@ pom.xml.asc /.nrepl-port .hgignore .hg/ +results \ No newline at end of file diff --git a/contrib/clojure-package/examples/infer/objectdetector/README.md b/contrib/clojure-package/examples/infer/objectdetector/README.md index 921c53e046d3..ec092a296a96 100644 --- a/contrib/clojure-package/examples/infer/objectdetector/README.md +++ b/contrib/clojure-package/examples/infer/objectdetector/README.md @@ -16,6 +16,9 @@ $ ./scripts/get_ssd_data.sh $ $ lein run -- --help $ lein run -- -m models/resnet50_ssd/resnet50_ssd_model -i images/dog.jpg -d images/ +$ +$ # or the available lein alias +$ lein run-detector $ $ lein uberjar $ java -jar target/objectdetector-0.1.0-SNAPSHOT-standalone.jar --help diff --git a/contrib/clojure-package/examples/infer/objectdetector/project.clj b/contrib/clojure-package/examples/infer/objectdetector/project.clj index 4501f14a358e..efdd30c06f05 100644 --- a/contrib/clojure-package/examples/infer/objectdetector/project.clj +++ b/contrib/clojure-package/examples/infer/objectdetector/project.clj @@ -17,9 +17,12 @@ (defproject objectdetector "0.1.0-SNAPSHOT" :description "Object detection using infer with MXNet" + :repositories [["vendredi" "https://repository.hellonico.info/repository/hellonico/"]] :plugins [[lein-cljfmt "0.5.7"]] + :aliases {"run-detector" ["run" "--" "-m" "models/resnet50_ssd/resnet50_ssd_model" "-i" "images/dog.jpg" "-d" "images/"]} :dependencies [[org.clojure/clojure "1.9.0"] [org.clojure/tools.cli "0.4.1"] + [origami "4.0.0-2"] [org.apache.mxnet.contrib.clojure/clojure-mxnet "1.5.0-SNAPSHOT"]] :main ^:skip-aot infer.objectdetector-example :profiles {:uberjar {:aot :all}}) diff --git a/contrib/clojure-package/examples/infer/objectdetector/src/infer/draw.clj b/contrib/clojure-package/examples/infer/objectdetector/src/infer/draw.clj new file mode 100644 index 000000000000..d29b34b5c22a --- /dev/null +++ b/contrib/clojure-package/examples/infer/objectdetector/src/infer/draw.clj @@ -0,0 +1,44 @@ +;; Licensed to the Apache Software Foundation (ASF) under one or more +;; contributor license agreements. See the NOTICE file distributed with +;; this work for additional information regarding copyright ownership. +;; The ASF licenses this file to You under the Apache License, Version 2.0 +;; (the "License"); you may not use this file except in compliance with +;; the License. You may obtain a copy of the License at +;; +;; http://www.apache.org/licenses/LICENSE-2.0 +;; +;; Unless required by applicable law or agreed to in writing, software +;; distributed under the License is distributed on an "AS IS" BASIS, +;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +;; See the License for the specific language governing permissions and +;; limitations under the License. +;; + +(ns infer.draw + (:require + [opencv4.colors.rgb :as rgb] + [opencv4.core :refer [FONT_HERSHEY_PLAIN imread imwrite new-point put-text! rectangle]])) + +(defn black-boxes! [img results] + (doseq [{confidence :confidence label :label top-left :top-left bottom-right :bottom-right} results] + (let [w (.width img) + h (.height img) + top-left-p (new-point (int (* w (first top-left))) (int (* h (second top-left)))) + bottom-right-p (new-point (int (* w (first bottom-right))) (int (* h (second bottom-right))))] + (if (< 15 confidence) + (do + (rectangle img top-left-p bottom-right-p rgb/white 1) + (put-text! img + (str label "[" confidence "% ]") + top-left-p + FONT_HERSHEY_PLAIN + 1.0 + rgb/white 1))))) + img) + +(defn draw-bounds [image results output-dir] + (let [out-file (str output-dir "/" (.getName (clojure.java.io/as-file image)))] + (-> image + (imread) + (black-boxes! results) + (imwrite out-file)))) \ No newline at end of file diff --git a/contrib/clojure-package/examples/infer/objectdetector/src/infer/objectdetector_example.clj b/contrib/clojure-package/examples/infer/objectdetector/src/infer/objectdetector_example.clj index 5c30e5db63fe..6010ddcafe47 100644 --- a/contrib/clojure-package/examples/infer/objectdetector/src/infer/objectdetector_example.clj +++ b/contrib/clojure-package/examples/infer/objectdetector/src/infer/objectdetector_example.clj @@ -20,6 +20,7 @@ [org.apache.clojure-mxnet.infer :as infer] [org.apache.clojure-mxnet.layout :as layout] [clojure.java.io :as io] + [infer.draw :as draw] [clojure.string :refer [join]] [clojure.tools.cli :refer [parse-opts]]) (:gen-class)) @@ -45,37 +46,49 @@ ["-i" "--input-image IMAGE" "Input image" :default "images/dog.jpg" :validate [check-valid-file "Input file not found"]] + ["-o" "--output-dir IMAGE_DIR" "Output directory. Defaults to results" + :default "results/" + :validate [check-valid-dir "Output directory not found"]] ["-d" "--input-dir IMAGE_DIR" "Input directory" :default "images/" :validate [check-valid-dir "Input directory not found"]] ["-h" "--help"]]) -(defn print-predictions - "Print image detector predictions for the given input file" - [predictions width height] - (println (apply str (repeat 80 "="))) - (doseq [{:keys [class prob x-min y-min x-max y-max]} predictions] - (println (format - "Class: %s Prob=%.5f Coords=(%.3f, %.3f, %.3f, %.3f)" - class - prob - (* x-min width) - (* y-min height) - (* x-max width) - (* y-max height)))) - (println (apply str (repeat 80 "=")))) +(defn result->map [{:keys [class prob x-min y-min x-max y-max]}] + (hash-map + :label class + :confidence (int (* 100 prob)) + :top-left [x-min y-min] + :bottom-right [x-max y-max])) + +(defn print-results [results] + (doseq [_r results] + (println (format "Class: %s Confidence=%s Coords=(%s, %s)" + (_r :label) + (_r :confidence) + (_r :top-left) + (_r :bottom-right))))) + +(defn process-results [images results output-dir] + (dotimes [i (count images)] + (let [image (nth images i) _results (map result->map (nth results i))] + (println "processing: " image) + (print-results _results) + (draw/draw-bounds image _results output-dir)))) (defn detect-single-image "Detect objects in a single image and print top-5 predictions" - [detector input-image] + [detector input-image output-dir] (let [image (infer/load-image-from-file input-image) - topk 5 - [predictions] (infer/detect-objects detector image topk)] - predictions)) + topk 5] + (process-results + [input-image] + (infer/detect-objects detector image topk) + output-dir))) (defn detect-images-in-dir "Detect objects in all jpg images in the directory" - [detector input-dir] + [detector input-dir output-dir] (let [batch-size 20 image-file-batches (->> input-dir io/file @@ -84,15 +97,18 @@ (filter #(re-matches #".*\.jpg$" (.getPath %))) (mapv #(.getPath %)) (partition-all batch-size))] - (apply concat (for [image-files image-file-batches] - (let [image-batch (infer/load-image-paths image-files) - topk 5] - (infer/detect-objects-batch detector image-batch topk)))))) + (doall + (for [image-files image-file-batches] + (let [image-batch (infer/load-image-paths image-files) topk 5] + (process-results + image-files + (infer/detect-objects-batch detector image-batch topk) + output-dir)))))) (defn run-detector "Runs an image detector based on options provided" [options] - (let [{:keys [model-path-prefix input-image input-dir + (let [{:keys [model-path-prefix input-image input-dir output-dir device device-id]} options width 512 height 512 descriptors [{:name "data" @@ -103,12 +119,11 @@ detector (infer/create-object-detector factory {:contexts [(context/default-context)]})] + (println "Output results to:" output-dir ":" (.mkdir (io/file output-dir))) (println "Object detection on a single image") - (print-predictions (detect-single-image detector input-image) width height) - (println "\n") + (detect-single-image detector input-image output-dir) (println "Object detection on images in a directory") - (doseq [predictions (detect-images-in-dir detector input-dir)] - (print-predictions predictions width height)))) + (detect-images-in-dir detector input-dir output-dir))) (defn -main [& args] diff --git a/contrib/clojure-package/examples/neural-style/project.clj b/contrib/clojure-package/examples/neural-style/project.clj index b6d29f7c0e87..8a5d52550eb5 100644 --- a/contrib/clojure-package/examples/neural-style/project.clj +++ b/contrib/clojure-package/examples/neural-style/project.clj @@ -18,8 +18,8 @@ (defproject neural-style "0.1.0-SNAPSHOT" :description "Neural Style Transfer with MXNet" :plugins [[lein-cljfmt "0.5.7"]] + :repositories [["vendredi" {:url "https://repository.hellonico.info/repository/hellonico/"}]] :dependencies [[org.clojure/clojure "1.9.0"] [org.apache.mxnet.contrib.clojure/clojure-mxnet "1.5.0-SNAPSHOT"] - [net.mikera/imagez "0.12.0"] - [thinktopic/think.image "0.4.16"]] - :main neural-style.core) + [origami "4.0.0-2"]] + :main neural-style.core) \ No newline at end of file diff --git a/contrib/clojure-package/examples/neural-style/src/neural_style/core.clj b/contrib/clojure-package/examples/neural-style/src/neural_style/core.clj index ac1f537f1c26..aa4c44717561 100644 --- a/contrib/clojure-package/examples/neural-style/src/neural_style/core.clj +++ b/contrib/clojure-package/examples/neural-style/src/neural_style/core.clj @@ -26,9 +26,8 @@ [org.apache.clojure-mxnet.symbol :as sym] [clojure.java.io :as io] [clojure.java.shell :refer [sh]] - [mikera.image.core :as img] - [mikera.image.filters :as img-filter] - [think.image.pixel :as pixel] + [opencv4.core :as cv] + [opencv4.utils :as cvu] [neural-style.model-vgg-19 :as model-vgg-19]) (:gen-class));; An Implementation of the paper A Neural Algorithm of Artistic Style ;;by Leon A. Gatys, Alexander S. Ecker, and Matthias Bethge @@ -41,63 +40,63 @@ (def model-path "model/vgg19.params") (def max-long-edge 600) ;; resize the content image (def style-weight 1) ;; the weight for the style image -(def content-weight 5) ;; the weight for the content image -(def blur-radius 1) ;; the blur filter radius +(def content-weight 3) ;; the weight for the content image +(def blur-radius 5) ;; the blur filter radius (def output-dir "output") (def lr 10.0) ;; the learning rate (def tv-weight 0.01) ;; the magnitude on the tv loss (def num-epochs 1000) -(def num-channels 3) -(defn image->ndarray [simg] - (let [h (img/height simg) - w (img/width simg) - pixels (img/get-pixels simg) - ;; normalize the pixels for vgg19 - rgb-pixels (reduce (fn [result pixel] - (let [[rs gs bs] result - [r g b _] (pixel/unpack-pixel pixel)] - [(conj rs (- r 123.68)) - (conj gs (- g 116.779)) - (conj bs (- b 103.939))])) - [[] [] []] - pixels)] - (println "The resized image is size " {:height h :width w}) - (-> rgb-pixels - (flatten) - (ndarray/array [1 num-channels h w])))) +;;;; +; IMAGE MANIPULATION +;;;; + +(defn image->ndarray + "normalize the pixels for vgg19" + [simg] + (let [h (.height simg) w (.width simg)] + (println "The nd image size is:" {:height h :width w}) + (-> simg + (cv/convert-to! cv/CV_8SC3 0.5) + (cv/add! (cv/new-scalar -103.939 -116.779 -123.68) ) + (cvu/mat->flat-rgb-array) + (ndarray/array [1 (.channels simg) h w])))) + +(defn ndarray->image [img] + (let [nd (ndarray/->vec img) + [_ _ h w] (mx-shape/->vec (ndarray/shape img)) + to-cv1 (fn [bytes h w] (cv/>> (cv/new-mat h w cv/CV_8S) (byte-array bytes))) + byte-arrays (reverse (partition (* h w) nd)) + mats (map #(to-cv1 % h w) byte-arrays)] + (-> mats + (cv/merge! (cv/new-mat h w cv/CV_8SC3)) + (cv/add! (cv/new-scalar 103.939 116.779 123.68)) + (cv/convert-to! cv/CV_8UC3 2)))) (defn preprocess-content-image [path short-edge] - (let [simg (img/load-image path) - _ (println "The content image is size " {:height (img/height simg) :width (img/width simg)}) - factor (/ short-edge (img/width simg)) - resized-img (img/resize simg (* (img/width simg) factor) (* (img/height simg) factor)) - new-height (img/height resized-img) - new-width (img/width resized-img)] - (image->ndarray resized-img))) + (-> path + (cv/imread) + (#(cvu/resize-by % (/ short-edge (.width %)))) + (image->ndarray))) (defn preprocess-style-image [path shape-vec] - (let [[_ _ h w] shape-vec - simg (img/load-image path) - _ (println "The image is size " {:height (img/height simg) :width (img/width simg)}) - resized-img (img/resize simg w h)] - (image->ndarray resized-img))) + (let [[_ _ h w] shape-vec] + (println "The style image is size " {:height h :width w}) + (-> path + (cv/imread) + (cv/resize! (cv/new-size w h)) + (image->ndarray)))) -(defn postprocess-image [img] - (let [datas (ndarray/->vec img) - image-shape (mx-shape/->vec (ndarray/shape img)) - spatial-size (* (get image-shape 2) (get image-shape 3)) - [rs gs bs] (doall (partition spatial-size datas)) - pixels (mapv (fn [r g b] - (pixel/pack-pixel - (int (+ r 123.68)) - (int (+ g 116.779)) - (int (+ b 103.939)) - (int 255))) - rs gs bs) - new-image (img/new-image (get image-shape 3) (get image-shape 2)) - _ (img/set-pixels new-image (int-array pixels))] - new-image)) +(defn save-image [img filename radius blur?] + (println "Saving image:" filename) + (-> img + (ndarray->image) + (#(if blur? (cv/blur! % (cv/new-size blur-radius blur-radius)) %)) + (cv/imwrite filename))) + +;;;; +; TRAINING +;;;; (defn style-gram-symbol [input-size style] (let [[_ output-shape _] (sym/infer-shape style {:data [1 3 (first input-size) (second input-size)]}) @@ -125,27 +124,6 @@ content-loss (sym/sum (sym/square (sym/- cvar content)))] {:style-loss (sym/group gram-loss) :content-loss content-loss})) -(defn old-clip [v] - (mapv (fn [a] (cond - (neg? a) 0 - (> a 255) 255 - :else a)) - v)) - -(defn clip [a] - (cond - (neg? a) 0 - (> a 255) 255 - :else a)) - -(defn save-image [img filename radius blur?] - (let [filtered-image (if blur? - ((img-filter/box-blur blur-radius blur-radius) (postprocess-image img)) - (postprocess-image img))] - (do - ;(img/show filtered-image) ;; Uncomment to have the image display - (img/write filtered-image filename "png")))) - (defn get-tv-grad-executor [img ctx tv-weight] (when (pos? tv-weight) (let [img-shape (mx-shape/->vec (ndarray/shape img)) @@ -163,7 +141,7 @@ (sym/bind out ctx {"img" img "kernel" kernel})))) (defn train - ([devs] (train devs 20)) + ([devs] (train devs 30)) ([devs n-epochs] (let [dev (first devs) content-np (preprocess-content-image content-image max-long-edge) @@ -244,9 +222,8 @@ (when (zero? (mod i 2)) (save-image (ndarray/copy img) (str output-dir "/out_" i ".png") blur-radius true))) (ndarray/set old-img img)) - ; (save-image (ndarray/copy img) (str output-dir "/final.png") 0 false) - ; (postprocess-image img) - ))) + (save-image (ndarray/copy img) (str output-dir "/final.png") 0 false) + (ndarray->image img)))) (defn -main [& args] ;;; Note this only works on cpu right now diff --git a/contrib/clojure-package/examples/neural-style/test/neural_style/vgg_19_test.clj b/contrib/clojure-package/examples/neural-style/test/neural_style/vgg_19_test.clj index a7c978607e4f..83be4a88bb3b 100644 --- a/contrib/clojure-package/examples/neural-style/test/neural_style/vgg_19_test.clj +++ b/contrib/clojure-package/examples/neural-style/test/neural_style/vgg_19_test.clj @@ -18,7 +18,7 @@ (ns neural-style.vgg-19-test (:require [clojure.test :refer :all] - [mikera.image.core :as img] + [opencv4.core :as cv] [clojure.java.io :as io] [org.apache.clojure-mxnet.ndarray :as ndarray] [org.apache.clojure-mxnet.context :as context] @@ -26,9 +26,8 @@ (defn pic-to-ndarray-vec[path] (-> path - img/load-image - neural/image->ndarray - ndarray/->vec)) + cv/imread + neural/image->ndarray)) (defn last-modified-check[x] (let [t (- (System/currentTimeMillis) (.lastModified x)) ] @@ -48,6 +47,4 @@ (deftest vgg-19-test (neural/train [(context/cpu)] 3) - (is (not (nil? (latest-pic-to-ndarray-vec "output"))))) -; generated file different depending on the platform :/ -; (pic-to-ndarray-vec "test/ref_out_2.png")))) \ No newline at end of file + (is (not (nil? (latest-pic-to-ndarray-vec "output"))))) \ No newline at end of file diff --git a/contrib/clojure-package/examples/pre-trained-models/README.md b/contrib/clojure-package/examples/pre-trained-models/README.md index 751109f7bb13..b0996da69a10 100644 --- a/contrib/clojure-package/examples/pre-trained-models/README.md +++ b/contrib/clojure-package/examples/pre-trained-models/README.md @@ -13,6 +13,16 @@ The `predict-image.clj` file loads up the pre-trained resnet-152 model and uses *To use run download-reset-152.sh to get the model params and json * +Run the example with the available leiningen alias: + +``` +$ lein predict-image +# +# or with your own image: +# +$ lein predict-image +``` + ## Fine Tune from pretrained models diff --git a/contrib/clojure-package/examples/pre-trained-models/project.clj b/contrib/clojure-package/examples/pre-trained-models/project.clj index 11e002503464..94aa8b9959e7 100644 --- a/contrib/clojure-package/examples/pre-trained-models/project.clj +++ b/contrib/clojure-package/examples/pre-trained-models/project.clj @@ -18,8 +18,9 @@ (defproject pre-trained-models "0.1.0-SNAPSHOT" :description "Example of using pre-trained models with MXNet" :plugins [[lein-cljfmt "0.5.7"]] + :repositories [["vendredi" {:url "https://repository.hellonico.info/repository/hellonico/"}]] + :aliases {"predict-image" ["run" "-m" "pre-trained-models.predict-image" ]} :dependencies [[org.clojure/clojure "1.9.0"] [org.apache.mxnet.contrib.clojure/clojure-mxnet "1.5.0-SNAPSHOT"] - [net.mikera/imagez "0.12.0"] - [thinktopic/think.image "0.4.16"]] + [origami "4.0.0-2"]] :main pre-trained-models.fine-tune) diff --git a/contrib/clojure-package/examples/pre-trained-models/src/pre_trained_models/predict_image.clj b/contrib/clojure-package/examples/pre-trained-models/src/pre_trained_models/predict_image.clj index 71202bc000f9..4df641da70c1 100644 --- a/contrib/clojure-package/examples/pre-trained-models/src/pre_trained_models/predict_image.clj +++ b/contrib/clojure-package/examples/pre-trained-models/src/pre_trained_models/predict_image.clj @@ -22,8 +22,8 @@ [org.apache.clojure-mxnet.ndarray :as ndarray] [org.apache.clojure-mxnet.shape :as mx-shape] [org.apache.clojure-mxnet.symbol :as sym] - [mikera.image.core :as img] - [think.image.pixel :as pixel])) + [opencv4.core :as cv] + [opencv4.utils :as cvu])) ;; based on https://mxnet.incubator.apache.org/tutorials/python/predict_image.html @@ -40,21 +40,13 @@ (io/copy in out))) (defn get-image [url show?] - (let [fname "test-image.jpg" - _ (download url fname) - image (-> (img/load-image fname) - (img/resize h w)) - pixels (img/get-pixels image) - rgb-pixels (reduce (fn [result pixel] - (let [[rs gs bs] result - [r g b _] (pixel/unpack-pixel pixel)] - [(conj rs r) (conj gs g) (conj bs b)])) - [[] [] []] - pixels)] - (when show? (img/show image)) - (-> rgb-pixels - (flatten) - (ndarray/array [1 num-channels h w])))) + (-> url + (cvu/mat-from-url) + (cv/resize! (cv/new-size h w)) + (#(do (if show? (cvu/imshow %)) %)) + (cv/convert-to! cv/CV_8SC3 0.5) + (cvu/mat->flat-rgb-array) + (ndarray/array [1 num-channels h w]))) (defn predict [img-url show?] (let [mod (m/load-checkpoint {:prefix (str model-dir "/resnet-152") :epoch 0}) @@ -90,6 +82,13 @@ (ndarray/shape) (mx-shape/->vec)))) +(defn -main [& args] + (println + (predict + (or (first args) + "https://raw.githubusercontent.com/dmlc/web-data/master/mxnet/doc/tutorials/python/predict_image/cat.jpg" ) + true))) + (comment (predict "https://raw.githubusercontent.com/dmlc/web-data/master/mxnet/doc/tutorials/python/predict_image/cat.jpg" true)