rlm@356: #+title: Fun with Gabor Filters rlm@356: #+author: Robert McIntyre rlm@356: #+email: rlm@mit.edu rlm@356: #+description: gabor filters in clojure with opencv rlm@356: #+keywords: computer vision, jMonkeyEngine3, clojure, opencv rlm@356: #+SETUPFILE: ../../aurellem/org/setup.org rlm@356: #+INCLUDE: ../../aurellem/org/level-0.org rlm@356: #+babel: :mkdirp yes :noweb yes :exports both rlm@356: rlm@356: rlm@356: rlm@356: #+name: gabor rlm@356: #+begin_src clojure rlm@357: (ns cortex.gabor rlm@357: (:import org.opencv.core.CvType) rlm@357: (:import java.awt.image.BufferedImage) rlm@357: (:import ij.ImagePlus) rlm@358: (:import org.opencv.core.Mat) rlm@357: (:use cortex.sense) rlm@357: (:use cortex.util) rlm@357: ) rlm@356: rlm@356: (defn load-opencv rlm@356: "Load the opencv native library. Must be called before any OpenCV rlm@356: stuff is used." rlm@356: [] rlm@356: (clojure.lang.RT/loadLibrary "opencv_java249")) rlm@356: rlm@358: (defn make-kernel [] rlm@358: (let [r (org.opencv.core.Mat. 5 5 CvType/CV_32F)] rlm@358: (.put r 0 0 (float-array (map (fn [_] (rand)) (range 25)))) rlm@358: (println (.dump r)) rlm@358: rlm@358: ;;r rlm@358: rlm@359: (org.opencv.core.MatOfFloat. (float-array [0.5])) rlm@358: )) rlm@356: rlm@359: (defn gabor-kernel [sigma aspect-ratio theta wavelength phase-offset] rlm@359: rlm@359: ;; first, find the size of the kernel which is required rlm@359: (let [square #(expt % 2) rlm@359: rotated (fn [[x y]] rlm@359: [(+ (* x (Math/cos theta)) (* y (Math/sin theta))) rlm@359: (- (* y (Math/cos theta)) (* x (Math/sin theta)))]) rlm@359: rlm@359: gaussian (fn [[x y]] rlm@359: (let [[x' y'] (rotated [x y])] rlm@359: (Math/exp (- (/ (+ (square x') rlm@359: (square (* aspect-ratio y'))) rlm@359: (* 2 (square sigma))))))) rlm@359: sinusoid (fn [[x y]] rlm@359: (let [[x' y'] (rotated [x y])] rlm@359: (Math/cos rlm@359: (+ (* 2 Math/PI (/ x' wavelength)) rlm@359: phase-offset)))) rlm@359: rlm@359: half-width (max rlm@359: (int (* 5 (/ sigma aspect-ratio))) rlm@359: (int (* 5 sigma)) rlm@359: (int (* 5 (/ aspect-ratio sigma)))) rlm@359: rlm@359: grid (let [axis (range (- half-width) (inc half-width))] rlm@359: (for [y (reverse axis) x axis] (vector x y))) rlm@359: rlm@359: scale (reduce + (map gaussian grid)) rlm@359: rlm@359: gabor (fn [[x y :as coord]] rlm@359: (* (sinusoid coord) (gaussian coord) scale)) rlm@359: rlm@359: mat-width (+ 1 (* 2 half-width)) rlm@359: mat (Mat. mat-width mat-width CvType/CV_32F)] rlm@359: rlm@359: rlm@359: (.put mat 0 0 (float-array (map gabor grid))) rlm@359: mat rlm@359: rlm@359: ;;(map gabor grid) rlm@359: rlm@359: )) rlm@359: rlm@359: rlm@359: (defn show-kernel [kernel] rlm@359: (let [output "/home/r/proj/cortex/tmp/kernel.png"] rlm@359: (org.opencv.highgui.Highgui/imwrite output kernel) rlm@359: (view (ImagePlus. output)))) rlm@359: rlm@359: (defn print-kernel [kernel] rlm@359: (println (.dump kernel))) rlm@359: rlm@359: rlm@359: rlm@359: rlm@359: rlm@359: rlm@359: rlm@359: rlm@359: rlm@359: rlm@357: (defn convolve-practice [] rlm@357: (let [input "/home/r/proj/cortex/images/dominos.jpg" rlm@357: rlm@357: rlm@357: output "/home/r/ppp.png" rlm@356: rlm@357: i (org.opencv.highgui.Highgui/imread input) rlm@358: rlm@358: kernel (make-kernel) rlm@358: rlm@358: new-mat (Mat.) rlm@358: rlm@357: ] rlm@356: rlm@358: (org.opencv.imgproc.Imgproc/filter2D i new-mat CvType/CV_32F (make-kernel)) rlm@358: rlm@358: (org.opencv.highgui.Highgui/imwrite "/home/r/ppp.png" new-mat) rlm@358: rlm@357: (view (ImagePlus. input)) rlm@357: (view (ImagePlus. output)) rlm@358: rlm@357: )) rlm@357: rlm@357: rlm@357: rlm@357: rlm@357: rlm@357: rlm@357: rlm@357: (comment rlm@357: ;; these work rlm@357: (def i (org.opencv.highgui.Highgui/imread rlm@357: "/home/r/proj/cortex/images/dominos.jpg")) rlm@357: rlm@357: (org.opencv.highgui.Highgui/imwrite "/home/r/ppp.png" i) rlm@357: ) rlm@356: #+end_src rlm@356: rlm@356: rlm@356: rlm@356: * COMMENT Generate Source rlm@356: #+begin_src clojure :tangle ../src/cortex/gabor.clj rlm@356: <> rlm@356: #+end_src