You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by cm...@apache.org on 2019/01/16 22:28:45 UTC
[incubator-mxnet] branch master updated: #13813 examples with
opencv4/origami (#13813)
This is an automated email from the ASF dual-hosted git repository.
cmeier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git
The following commit(s) were added to refs/heads/master by this push:
new 754ff76 #13813 examples with opencv4/origami (#13813)
754ff76 is described below
commit 754ff7669b4b3d481a80d734d79921e0c5d58bce
Author: Nicolas Modrzyk <he...@gmail.com>
AuthorDate: Thu Jan 17 07:28:25 2019 +0900
#13813 examples with opencv4/origami (#13813)
---
contrib/clojure-package/examples/gan/.gitignore | 1 +
contrib/clojure-package/examples/gan/project.clj | 7 +-
.../clojure-package/examples/gan/src/gan/viz.clj | 56 +++------
.../examples/infer/objectdetector/.gitignore | 1 +
.../examples/infer/objectdetector/README.md | 3 +
.../examples/infer/objectdetector/project.clj | 3 +
.../infer/objectdetector/src/infer/draw.clj | 44 +++++++
.../src/infer/objectdetector_example.clj | 71 +++++++-----
.../examples/neural-style/project.clj | 6 +-
.../neural-style/src/neural_style/core.clj | 127 +++++++++------------
.../neural-style/test/neural_style/vgg_19_test.clj | 11 +-
.../examples/pre-trained-models/README.md | 10 ++
.../examples/pre-trained-models/project.clj | 5 +-
.../src/pre_trained_models/predict_image.clj | 33 +++---
14 files changed, 201 insertions(+), 177 deletions(-)
diff --git a/contrib/clojure-package/examples/gan/.gitignore b/contrib/clojure-package/examples/gan/.gitignore
index c53038e..ea80131 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 a326f7a..4393987 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-3"]
]
- :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 67f7880..08da53c 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 35491f1..a1f0468 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 921c53e..ec092a2 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 4501f14..cdd9a89 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-3"]
[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 0000000..d29b34b
--- /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 5c30e5d..6010ddc 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 b6d29f7..2614a69 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-3"]]
+ :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 ac1f537..aa4c447 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 a7c9786..83be4a8 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 751109f..b0996da 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 <url_or_path_to_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 11e0025..e4f6939 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-3"]]
: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 71202bc..4df641d 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)