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    ))
Tory Anderson avatar
Tory Anderson
Full-time Web App Engineer, Digital Humanist, Researcher, Computer Psychologist