home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
vis-ftp.cs.umass.edu
/
vis-ftp.cs.umass.edu.tar
/
vis-ftp.cs.umass.edu
/
pub
/
Software
/
ASCENDER
/
ascendMar8.tar
/
UMass
/
umass-system.lisp
< prev
Wrap
Lisp/Scheme
|
1996-03-08
|
22KB
|
576 lines
;;; UMass Building Extraction System
;;; Copyright 1995, University of Massachusetts, Amherst MA.
;;; (c) all rights reserved.
(in-package 'cme)
(defvar *umass-base-path* "$RADIUSCODE/UMass/")
(defun full-umass-path (filename &optional (base-path *umass-base-path*))
(concatenate 'string base-path filename))
(defun translated-unix-path (pathname)
(format nil "~a" (ic::translate-pathname pathname)))
(defvar user::*boldt-directory* (full-umass-path "BoldtNew/")
"directory containing Boldt Line code")
(defvar user::*isr2-directory* (full-umass-path "ISR/")
"directory containing ISR database system")
(defvar user::*epipolar-directory* (full-umass-path "Epipolar/")
"directory containing epipolar matcher")
(defvar user::*base-temp-directory* (full-umass-path "Temp/")
"directory for scratch files")
(defvar user::*temp-directory* (full-umass-path "Temp/")
"directory for scratch files")
(defvar user::*umass-compile* nil "used by UMass to recompile system")
(defvar *2dlines-propname* :2dlines)
(defvar *2dlines-filename* "temp_2d_lines.lines")
(defvar *2_5dlines-propname* :2_5dlines)
(defvar *2_5dlines-filename* "temp_2pt5d_lines.lines")
(defvar *tempdir-propname* :tempdir)
(defvar *2d-line-fsname* "UMass Boldt Lines")
(defvar *2d-building-fsname* "UMass 2d Buildings")
(defvar *3d-building-fsname* "UMass 3d Buildings")
(defvar *3d-hypotheses-fsname* "UMass 3d Hypotheses")
(defvar *triang-in-filename* "triangin.dat")
(defvar *triang-out-filename* "triangout.dat")
(defvar *triang-c-filename* (full-umass-path "Triangulate/tri"))
(defvar *triang-infile* nil)
(defvar *triang-outfile* nil)
(defvar *site-3d-world* nil "3d world of site model currently being constructed")
;;;Get package names defined right now to avoid problems later on
(unless (find-package 'isr2) (make-package 'isr2))
(unless (find-package 'epipolar) (make-package 'epipolar :nicknames '(epi)))
(unless (find-package 'boldt) (make-package 'boldt))
(unless (find-package 'cg) (make-package 'cg)) ;;computational geometry
(defun load-umass-file (filename &optional (base-path *umass-base-path*))
(load (full-umass-path filename base-path)))
(defun load-umass-system ()
(print "Loading UMass system...")
(load-umass-file "load-isr2" user::*isr2-directory*)
(load-umass-file "load-epipolar" user::*epipolar-directory*)
(load-umass-file "LineFinder/topdown-line-finder")
(load-umass-file "BoldtNew/canny-boldt")
(load-umass-file "Arbitrate/arbitration")
(let ((working-directory (pwd)))
(lci::load-project (full-umass-path "BuildingFinder/poly.proj"))
;; (lci::load-project (full-umass-path "Triangulate/tri.proj"))
(load-umass-file "BuildingFinder/functions.lisp")
;;(load-umass-file "Triangulate/support.lisp")
(load-umass-file "BuildingFinder/Lisp/top-down-vrfy.lisp")
(set-working-directory working-directory))
(load-umass-file "Acquire/acquire-model")
t)
(define-image-calc-interaction-method com-load-umass-system ()
"Load UMass system into RCDE"
(load-umass-system))
(defun put-pathname-property (world pathname property-name)
(let ((pathname (translated-unix-path pathname)))
(ic::put-prop world pathname property-name)))
(defun find-fs-named (world namestring)
"Return feature set with the given name, else nil."
(find (string namestring) (feature-sets world)
:key #'name :test #'string-equal))
(defun get-or-make-2d-feature-set (2dworld fsname)
(let ((fs (find-fs-named 2dworld fsname)))
(unless fs
(setf fs (make-2d-feature-set :world 2dworld :name fsname))
(dolist (view (view-list 2dworld))
(add-view fs view :sensitize t)))
fs))
(defun clear-fs (fs)
(mapc
#'(lambda (x)
(when (equal (type-of x) 'ISR-LINE-TOKENSET-OBJECT) ;;BobC 2/21/96
(isr2::destroy* (tokenset x))) ;;reclaim memory from ISR
(remove-object x fs))
(inferiors fs)))
;;;-------------------------------------------------------
(defun init-umass-site-model (3dworld)
(format t "Initializing UMass site model for ~a~%" (name 3dworld))
(setf user::*temp-directory*
(concatenate 'string user::*base-temp-directory*
(string (gensym "DIR")) "/"))
(format t "Creating temp directory ~s~%" user::*temp-directory*)
(ic::create-directory user::*temp-directory*)
(put-pathname-property 3dworld user::*temp-directory* *tempdir-propname*)
(setf *site-3d-world* 3dworld)
(let ((3dfs (make-3d-feature-set :world 3dworld
:name *3d-building-fsname*))
(3dhyp-fs (make-3d-feature-set :world 3dworld
:name *3d-hypotheses-fsname*)))
(dolist (view (view-list 3dworld))
(add-view 3dfs view :sensitize t))
(dolist (view (view-list 3dworld))
(add-view 3dhyp-fs view :sensitize nil))
(select-fs 3dworld 3dfs))
(dolist (2dworld (2d-worlds 3dworld))
(mapcar #'(lambda (name)
(make-2d-feature-set :world 2dworld :name name))
(list *2d-building-fsname*))
(let ((2dfs (find-fs-named 2dworld *2d-building-fsname*)))
(dolist (view (view-list 2dworld))
(add-view 2dfs view :sensitize t))
(select-fs 2dworld 2dfs)))
(rcde-init-epipolar-views 3dworld)
(setf *triang-infile* (translated-unix-path
(concatenate 'string user::*temp-directory* *triang-in-filename*)))
(setf *triang-outfile* (translated-unix-path
(concatenate 'string user::*temp-directory* *triang-out-filename*)))
(ic::put-prop 3dworld t :umass-site-model)
3dworld)
(define-image-calc-interaction-method com-init-umass-site-model ()
"Initialize a new UMass site model"
(let* ((pane (ic::pick-a-pane ic::self "Pick any pane showing the site"))
(topview (top-view pane))
(3dworld (3d-world topview)))
(init-umass-site-model 3dworld)))
(define-image-calc-interaction-method com-extract-boldt-lines ()
"Run Boldt line segment extractor."
(boldt::run-boldt-from-menu))
(defun makenewpath (pathname &key newtype newdir)
(merge-pathnames (make-pathname
:name (pathname-name pathname)
:type (or newtype (pathname-type pathname)))
(or newdir (directory-namestring pathname))))
(define-image-calc-interaction-method com-save-line-featuresets ()
"Save all 2D line featuresets."
(let* ((pane (ic::pick-a-pane ic::self "Pick any pane showing the site"))
(topview (top-view pane))
(3dworld (3d-world topview))
(fslist nil)
(defaultname (concatenate 'string
(replace-spaces-with-hyphens (string (name 3dworld)))
".linesets"))
(pathname nil))
(setf fslist (mapcan #'(lambda (w)
(let ((foo (find-fs-named w *2d-line-fsname*)))
(when foo (list foo))))
(2d-worlds 3dworld)))
(ic::with-cvv-items
(((directory "Directory: " :string :initial-value (format nil "~a" (pwd))
:documentation "Directory to save feature sets in")
(filename "Filename: " :string :value defaultname
:documentation "Filename for saving feature sets"))
:label "Save line featuresets")
(unless (probe-file directory)
(error "Directory ~a does not exist!" directory))
(format t "Saving ~d line featuresets for ~a~%"
(length fslist) (name 3dworld))
(setf pathname (makenewpath defaultname :newdir directory))
(with-open-file (file pathname :direction :output)
(format t "Saving into file ~a~%" pathname)
(format file ":ascender_line_file~%")
(format file "~d feature sets~%" (length fslist))
(dolist (fs fslist)
(let* ((tks (get-or-make-ISR-tokenset fs))
(newpath (makenewpath (tokensetname tks) :newtype "isr2"
:newdir directory)))
(setf (load-filename tks) (format nil "~a" newpath))
(format file "~s~%" (string (cme::name (cme::world fs))))
(write-isr-line-tokenset file tks :write-load-file t)))))))
(defun load-old-line-featuresets (3dworld pathname)
(format t "Loading line featuresets for ~a~%" (name 3dworld))
(load pathname)
(mapcar
#'(lambda (linefs)
(when linefs
(let ((isrobject
(find 'ISR-LINE-TOKENSET-OBJECT (inferiors linefs)
:key #'type-of :test #'equal))
(2dworld (world linefs)))
(dolist (view (view-list 2dworld))
(add-view linefs view)
(when isrobject
(put-pathname-property
2dworld
(c-filename isrobject)
*2dlines-propname*)
(put-pathname-property
2dworld
(c-filename isrobject)
*2_5dlines-propname*)))
)))
cme::*object-feature-sets*))
;;to be compatible with old files
(defun load-line-featuresets (3dworld pathname)
(load-old-line-featuresets 3dworld pathname))
(defun load-new-line-featuresets (3dworld pathname &key (clear-fs t))
(with-open-file (file pathname :direction :input)
(read-line file) ;;skip format header
(let ((numfs (read file)))
(read-line file) ;;skip rest of line
(format t "Loading ~d line featuresets for ~a~%" numfs (name 3dworld))
(dotimes (i numfs pathname)
(let* ((2dworldname (read file))
(2d-world (get-2d-world-named 2dworldname))
(fs (get-or-make-2d-feature-set 2d-world *2d-line-fsname*)))
(when clear-fs (clear-fs fs))
(add-object (read-isr-line-tokenset file) fs)
(process-object-updates)
(map 'nil #'refresh-view (view-list 2d-world)))))))
(define-image-calc-interaction-method com-load-line-featuresets ()
"Load 2D line featuresets."
(let* ((pane (ic::pick-a-pane ic::self "Pick any pane showing the site"))
(topview (top-view pane))
(3dworld (3d-world topview))
(old-format? nil))
(ic::with-cvv-items
(((pathname "Pathname: " :string :value (format nil "~a" (pwd))
:documentation "Full pathname for loading feature sets"))
; (clear-fs "Previous lines:" :assoc :alist
; (("Replace" :replace "Replace previous lines")
; ("Append" :append "Add to previous lines"))
; :documentation "What to do with previous line features"
; :initial-value :replace))
:label "Load line featuresets")
(with-open-file (file pathname :direction :input)
(unless (eq (read file) :ascender_line_file)
(setf old-format? t)))
(if old-format?
(load-old-line-featuresets 3dworld pathname)
(load-new-line-featuresets 3dworld pathname
:clear-fs t
;; :clear-fs (eq clear-fs :replace)
)))
t))
(defun read-tri-vert-list (filename)
(with-open-file (file filename :direction :input)
(let ((numverts (read file))
(vertlist nil))
(dotimes (i numverts vertlist)
(push (list (read file) (read file) (read file))
vertlist)))))
(defun read-init-guess-list (filename)
(with-open-file (file filename :direction :input)
(let ((numverts (read file))
(vertlist nil))
(dotimes (i numverts vertlist)
(push (list (read file) (read file) (read file))
vertlist)
(read file) (read file) (read file)))))
(defvar *arbitration-threshold* 0.5)
;;install-triangulated-building:
;;changed to select feature set first before creating the object, then
;;setting the selected feature set back to what it was. Not sure
;;why I have to do this, but the building was always ending up in
;;the selected feature set, in addition to the feature set I am
;;explicitly adding it to. --BobC Fri Sep 22,1995
;;added hypothesis arbitration -- Bob C Wed Feb 28
(defun add-building-to-featureset (object featureset)
(let ((selected-fs (selected-feature-set *site-3d-world*)))
(select-fs *site-3d-world* featureset)
(add-object object featureset)
(select-fs *site-3d-world* selected-fs)))
(defun install-triangulated-building (filename conf &key (initguess nil))
(let* ((selected-fs (selected-feature-set *site-3d-world*))
(hyp-fs (find-fs-named *site-3d-world* *3d-hypotheses-fsname*))
(build-fs (find-fs-named *site-3d-world* *3d-building-fsname*))
(vlist (if initguess
(read-init-guess-list filename)
(read-tri-vert-list filename))))
(when (and vlist (numberp (caar vlist)))
(select-fs *site-3d-world* hyp-fs)
(let* ((curve (make-3d-closed-curve
:vertices (make-vertex-array-from-vertex-list vlist)
:world *site-3d-world*))
(building (extrude-roof-curve curve))
(alternates (sort (competing-hypotheses vlist build-fs
*arbitration-threshold*)
#'> :key #'car)))
(ic::put-prop building conf :match-score)
(cond
((null alternates)
;;no competing hypotheses, just put wireframe in the site model
(add-building-to-featureset building build-fs))
((> (ic::get-prop (cadar alternates) :match-score) conf)
;;current site model building is better than the wireframe
(add-building-to-featureset building hyp-fs))
(t
;;replace current site model building with new wireframe
(remove-object (cadar alternates) build-fs)
(add-building-to-featureset (cadar alternates) hyp-fs)
(add-building-to-featureset building build-fs)))
(process-object-updates) ;;BobC 2/20/96
(select-fs *site-3d-world* selected-fs)
))))
(defvar *last-epi-slop* 1.0)
(defvar *last-epi-dtheta* 0.1)
(defvar *last-epi-support-percentage* 0.3)
(defvar *last-epi-minz* nil)
(defvar *last-epi-maxz* nil)
(defun popup-epipolar-menu ()
(ic::with-cvv-items
(((zmin "Min Z value: " :float :value *last-epi-minz*
:documentation "Minimum Z coordinate of a building rooftop")
(zmax "Max Z value: " :float :value *last-epi-maxz*
:documentation "Maximum Z coordinate of a building rooftop")
(support "Line support:" :float :value *last-epi-support-percentage*
:documentation "Minimum line support percentage allowed")
(slop "Pixel error: " :float :value *last-epi-slop*
:documentation "Amount of perpendicular slop in line endpoints")
(dtheta "Radian error: " :float :value *last-epi-dtheta*
:documentation "Amount of slop in line orientation (radians)")
(arb "Arbitration: " :float :value *arbitration-threshold*
:documentation "Amount of overlap defining alternate hypotheses"))
:label "Enter values for epipolar search")
(setf *last-epi-slop* slop *last-epi-dtheta* dtheta)
(setf *last-epi-minz* zmin *last-epi-maxz* zmax)
(setf *last-epi-support-percentage* support)
(setf *arbitration-threshold* arb)
(rcde-init-height-histograms zmin zmax)))
(define-image-calc-interaction-method com-match-triang-rooftops ()
"Match/triangulate rooftops from multiple views."
(let* ((pane (ic::pick-a-pane ic::self "Pick a pane containing 2d rooftops"))
(topview (top-view pane))
(2dworld (2d-world topview))
(3d-world (3d-world 2dworld)))
(unless (ic::get-prop 3d-world :umass-site-model)
(error "No UMass site model has been initialized for this 3D world"))
(popup-epipolar-menu)
(let* ((2dfs (find-fs-named 2dworld *2d-building-fsname*))
(count 0)
(curves (mapcan #'(lambda (x)
(when (eq (type-of x) 'cme::2d-curve) (list x)))
(inferiors 2dfs))))
(format t "~d curves to be matched/triangulated~%"
(length curves))
(dolist (curve curves)
(format t "Running matcher on curve ~d~%" (incf count))
(let ((match (rcde-run-epipolar-matcher 2dworld curve
:filename *triang-infile*
:endpoint-slop *last-epi-slop*
:delta-theta *last-epi-dtheta*)))
(format t "height estimate: ~,3f, match support: ~,3f~%"
(epi::epimatch-rough-zvalue match)
(epi::epimatch-peak-confidence match))
;;
;; Modified: Feb. 27, 1996
;; Christopher Jaynes
;; The triangulator was compiled as a standalone 'c' program
;; and is now called through a simple shell fork.
;;
;;
(shell (format nil "~a ~a ~a"
(translated-unix-path *triang-c-filename*)
*triang-infile*
*triang-outfile*))
;; (lci::triangulation *triang-infile* *triang-outfile*)
(remove-object curve 2dfs) ;;remove 2d roof hypothesis
(install-triangulated-building ;;and install 3D wireframe
*triang-outfile*
(epi::epimatch-peak-confidence match)))))
(epi::synch-epipolar-screen topview)
t))
(define-image-calc-interaction-method com-detect-rooftops ()
"Detect building rooftops in an image."
(popup-building-finder-menu)
t)
(define-image-calc-interaction-method com-acquire-model ()
"Acquire site model from this image."
;; (popup-acquire-buildings-menu))
(acquire-site-model))
(defparameter cme::*umass-menu-item-list*
(ic::make-menu-item-list
'("Reload Umass System" cme::com-load-umass-system
"Extract Boldt Lines" cme::com-extract-boldt-lines
;;;; "Install Image Lines" cme::com-install-line-file
"Save Line Featuresets" cme::com-save-line-featuresets
"Load Line Featuresets" cme::com-load-line-featuresets
"Initialize Site Model" cme::com-init-umass-site-model
"Detect Building Rooftops" cme::com-detect-rooftops
"Match/Triangulate Rooftops" cme::com-match-triang-rooftops
"Acquire Site Model" cme::com-acquire-model)))
(defun install-umass-pulldown-menu ()
(when (find "UMass" xw::*pulldown-menu-bar-item-list*
:key #'car :test #'string-equal)
(delete "UMass" xw::*pulldown-menu-bar-item-list*
:key #'car :test #'string-equal))
(when (find "LCI" xw::*pulldown-menu-bar-item-list*
:key #'car :test #'string-equal)
(delete "LCI" xw::*pulldown-menu-bar-item-list*
:key #'car :test #'string-equal))
(setf xw::*pulldown-menu-bar-item-list*
(ic::add-item-to-item-list
'("UMass" :menu cme::*umass-menu-item-list*
:documentation ("UMass Building Extraction System" ""))
xw::*pulldown-menu-bar-item-list*
:after-item-named "Panels"))
(setf xw::*pulldown-menu-bar-item-list*
(ic::add-item-to-item-list
'("LCI" :MENU *INTERFACE-MENU-ITEM-LIST*
:DOCUMENTATION ("Lisp-C/C++ Interface" ""))
xw::*pulldown-menu-bar-item-list*
:after-item-named "UMass"))
(ic::install-menus)
;;this is hokey, but the core-dumping bug is in CME's code
(when (probe-file "core")
(delete-file "core"))
t)
(defvar *already-loaded* nil)
(eval-when (eval load)
(print "Installing UMass pulldown menu")
(unless *already-loaded*
(load-umass-system)
(setf *already-loaded* t))
(install-umass-pulldown-menu))
;;======================================================================
#| OLD CODE THAT ISN'T USED ANYMORE -- BobC 2/6/96
(define-image-calc-interaction-method com-save-line-featuresets ()
"Save all installed 2D line featuresets."
(let* ((pane (ic::pick-a-pane ic::self "Pick any pane showing the site"))
(topview (top-view pane))
(3dworld (3d-world topview))
(fslist nil))
(setf fslist (mapcan #'(lambda (w)
(let ((foo (find-fs-named w *2d-line-fsname*)))
(when foo (list foo))))
(2d-worlds 3dworld)))
(ic::with-cvv-items
(((pathname "Pathname: " :string :value (format nil "~a" (pwd))
:documentation "Full pathname for saving feature sets"))
:label "Save line featuresets")
(format t "Saving ~d line featuresets for ~a~%"
(length fslist) (name 3dworld))
(dump-feature-sets pathname fslist))))
(defun load-line-featuresets (3dworld pathname)
(format t "Loading line featuresets for ~a~%" (name 3dworld))
(load pathname)
(mapcar
#'(lambda (linefs)
(when linefs
(let ((isrobject
(find 'ISR-LINE-TOKENSET-OBJECT (inferiors linefs)
:key #'type-of :test #'equal))
(2dworld (world linefs)))
(dolist (view (view-list 2dworld))
(add-view linefs view)
(when isrobject
(put-pathname-property
2dworld
(c-filename isrobject)
*2dlines-propname*)
(put-pathname-property
2dworld
(c-filename isrobject)
*2_5dlines-propname*))
))))
cme::*object-feature-sets*))
(defvar *last-line-filename* nil)
(defvar *last-image-filename* nil)
(defvar *last-archival-dir* nil)
(define-image-calc-interaction-method com-install-line-file ()
"Associate a file of 2D line segments with a 2D world."
(let* ((pane (ic::pick-a-pane ic::self "Pick a pane containing the 2d world"))
(topview (top-view pane))
(2dworld (2d-world topview))
(linefile (or (ic::get-prop 2dworld *2dlines-propname*)
*last-line-filename*)))
(ic::with-cvv-items
(((pathname "Line Pathname: " :string :value linefile
:documentation "Full pathname of 2d line segment file")
(image "Image Pathname: " :string :value *last-image-filename*
:documentation "RCDE image file that lines were computed from")
(directory "Archival Directory: " :string
:value *last-archival-dir*
:documentation "Directory for storing line file results"))
:label (format nil "~a: Install line file" (name 2dworld)))
(setf *last-line-filename* pathname)
(unless (probe-file pathname)
(error "Line file ~a does not exist!" pathname))
(setf *last-image-filename* image)
(unless (probe-file image)
(error "Image file ~a does not exist!" image))
(setf *last-archival-dir* directory)
(unless (probe-file directory)
(error "Directory ~a does not exist!" directory))
(format t "installing ~a into ~a~%" pathname (name 2dworld))
(let ((newpath (makenewpath pathname :newtype "lines" :newdir directory))
(isrpath (makenewpath pathname :newtype "isr2" :newdir directory)))
(format t "will create files ~a~%" newpath)
(format t " and ~a~%" isrpath)
(read-and-install-line-featureset
2dworld pathname image newpath isrpath *2d-line-fsname*)
(put-pathname-property 2dworld newpath *2dlines-propname*)
(put-pathname-property 2dworld newpath *2_5dlines-propname*)))))
;;;---------- something for reporting progress -----------
(defun overstrike-expression (oldexpr newexpr)
(let ((len (length (format nil "~a" oldexpr))))
(dotimes (i len)
(princ #\backspace))
(dotimes (i len)
(princ #\space))
(dotimes (i len)
(princ #\backspace)))
(format t "~a" newexpr))
(defvar *last-reported-number* nil)
(defun init-number-report (info-string number)
(format t "~a~d" info-string number)
(setf *last-reported-number* number))
(defun update-number-report (number)
(overstrike-expression *last-reported-number* number)
(setf *last-reported-number* number))
(defun end-number-report (&optional (end-string nil))
(format t "~a~%" (or end-string "")))
|#