Major Java-interop in Clojure
Table of Contents
This project was for a class in which we submitted java. I wrote this Clojure code to produce a Java class that could be run according to their specifications. So here is some of the first Clojure I ever wrote, long ago in grad school, utilizing the OpenCV system for computer vision.
Notice the heavy use of obscure (non-Clojurey) APIs on objexts, marked by all the (.XYZ ...)
lines.
(ns com.toryanderson.kbai
(:gen-class
:name com.toryanderson.kbai
:methods [#^{:static true} [solve [project4.VisualRavensProblem] String]])) ;; I am generating a java-callable class that exposes methods of the project4 problem
;; all these imports would be better in the ns statement above, but this was the first Clojure I had ever written
(import '[org.opencv.core Mat Size CvType MatOfPoint MatOfPoint2f Core]
'[org.opencv.highgui Highgui]
'[org.opencv.imgproc Imgproc])
(import '(project4 VisualRavensProblem VisualRavensFigure VisualProblemDealer))
(import '(project3 RavensProblem RavensFigure RavensObject RavensAttribute)) ; ; opencv was/is a java system for visual recognition. Here I bring in the Java libraries.
(clojure.lang.RT/loadLibrary org.opencv.core.Core/NATIVE_LIBRARY_NAME)
(declare compose-ravens-object compose-ravens-figure)
;;;;;;;;
(defn compose-ravens-object
"Given an input image contour, compose a RavensObject from it"
[contour name]
(let [obj (RavensObject. name) ;; xxx RavensObject constructor
attributes (.getAttributes obj)
adjusted-contour (MatOfPoint2f. (.toArray contour))
approx (MatOfPoint2f.) ; gets set by side-effects with do-set-approx
do-set-approx (Imgproc/approxPolyDP adjusted-contour approx (* 0.02 (Imgproc/arcLength adjusted-contour true)) true)
corners (int (.area (.size approx))) ; more-or-less
fill (get-fill contour) ; fill
area (int (Imgproc/contourArea contour))
angle (.angle (Imgproc/fitEllipse adjusted-contour)) ; angle ;; XXX broken for triangles, at least
moments (Imgproc/moments contour)
centroid (get-centroid moments) ; center, for use later
; left-of
; inside-of
print-string (format "Object Parameters---
corners: %d
fill: %f
area: %d
angle: %f
center: %s
above:
left-of:
inside-of:"
corners
fill
area
angle
centroid
)
]
(println print-string)
(doseq [ent
{"corners" corners "fill" fill "area" area "angle" angle "center" centroid}]
(.add attributes (RavensAttribute. (key ent) (str (val ent)))))
obj ))