Skip to content
Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
89 lines (78 sloc) 3.59 KB
; Albert Cardona 2008-11-16
; Released under the General Public License v2.0
;
; This ImageJ plugin creates a plot window which is dynamically updated as the
; ROI is moved across the image.
; Requires a line, polyline, freeline or rectangular ROI.
; Declare a namespace for this script
; with a set of imports specific for it.
(ns roi.profiler.dynamic
(:import (ij IJ)
(ij.gui Plot ProfilePlot Roi)
(java.awt.event MouseMotionAdapter WindowAdapter)
(java.util.concurrent Executors)))
; All functions declared with defn- (notice the minus sign) are private to this namespace.
(def *plot-width* 600)
(def *plot-height* 400)
(defn- create-profile-plot [imp]
(let [pp (ProfilePlot. imp)
data (.getProfile pp)
indices (double-array (range (count data)))
plot (Plot. "Profile" "Index" "Pixel value" indices data)]
(doto plot
(.setLineWidth 2)
(.setLimits 0 (count data)
(.getMin pp) (.getMax pp))
(.setSize *plot-width* *plot-height*))
plot))
(defn- create-empty-plot []
(let [data (float-array 1)
indices (float-array 1)
plot (Plot. "Profile" "Index" "Pixel value" indices data)]
(doto plot
(.setLimits 0 1 0 1)
(.setSize *plot-width* *plot-height*))
plot))
(let [valid [Roi/LINE Roi/POLYLINE Roi/FREELINE Roi/RECTANGLE]]
(defn- is-profilable [roi]
"Returns true if roi is not null and is one of the valid types: a linear roi or a rectangle."
(if roi
(if (some #{(.getType roi)} valid)
true
false)
false)))
(let [empty (create-empty-plot)]
(defn- update [plot-win imp]
"Update the plot window using the current ROI on the image, or set a blank plot if not profilable."
(let [roi (.getRoi imp)
plot-imp (.getImagePlus plot-win)]
(.setProcessor plot-imp nil (.getProcessor
(if (is-profilable roi)
(.getImagePlus (create-profile-plot imp))
empty))))))
(defn- setup [imp]
"Creates a plot window that monitors the line ROI of the image as it changes"
(let [canvas (.getCanvas (.getWindow imp))
plot-win (.show (create-profile-plot imp))
exec (Executors/newFixedThreadPool 1) ; An executor thread pool of 1 thread to run the plot updates
canvas-listener (proxy [MouseMotionAdapter] []
(mouseDragged [event]
; Submit an update job to the executor thread.
; The job is a function with no arguments, created on the fly with #(...)
; which executes the 'update' function with args plot-win and imp:
(.submit exec #(update plot-win imp) nil)))]
(.addMouseMotionListener canvas canvas-listener)
; Remove the mouse listener when the plot window is closed:
(.addWindowListener plot-win (proxy [WindowAdapter] []
(windowClosing [event]
; Tell the canvas to forget our mouse listener
(.removeMouseMotionListener canvas canvas-listener)
; Quit the executor pool
(.shutdown exec))))))
; Execute on the current image if any
(let [imp (IJ/getImage)]
(if imp
(if (is-profilable (.getRoi imp))
(setup imp)
(IJ/showMessage "Need a line or rectangular ROI!"))
(IJ/showMessage "Open an image first!")))
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.