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
/
BuildingFinder
/
Lisp
/
top-down-vrfy.lisp
< prev
Wrap
Lisp/Scheme
|
1995-11-17
|
7KB
|
216 lines
;;; TOP-DOWN-VRFY.LISP
;;;
;;; Routines to verify the existence of an edge in an image
;;; between to features that may be grouped together.
;;;
;;; Makes use of a top-down/local edge detector.
;;;
;;;
;;; Author: Christopher O. Jaynes
;;; Date: June 11, 1995
;;;
;;
;------------------------------------------------------------
; (c) Copyright 1995 by The University of Massachusetts
;------------------------------------------------------------
(in-package 'cme)
;;
;; Local line support is determined through an analysis of the local
;; intensity gradient. Lines are extracted, projected to the support
;; line and then a coverage length is computed.
;;
(defun image-line-support (image u1 v1 u2 v2 column-width percentage)
(let ((support (line-support-overlap image u1 v1 u2 v2 column-width)))
(if (> support percentage)
support
0.0)))
(defun line-support-overlap (image u1 v1 u2 v2 column-width)
(let* ((linevec (make-vec-2d u1 v1 u2 v2))
(pairs (sort-pairs (supporting-line-begin-end-pairs image u1 v1 u2 v2
column-width)))
(gaplength
(compute-support-gaps (car pairs) (cdr pairs) u1 v1 u2 v2)))
(- 1.0 (/ gaplength (linear-algebra::vector-length linevec)))))
(defun compute-support-gaps (first pairlist u1 v1 u2 v2)
(if (null first)
(linear-algebra::vector-length (make-vec-2d u1 v1 u2 v2))
(+ (car first) (compute-gap-lengths first pairlist)
(- (linear-algebra::vector-length
(make-vec-2d u1 v1 u2 v2))
(last-endpoint (cons first pairlist)))) ))
(defun compute-gap-lengths (first pairs)
(let ((next (car pairs)))
(if (null next)
0
(if (> (cadr next) (cadr first))
(+ (gap-distance first next)
(compute-gap-lengths next (cdr pairs)))
(compute-gap-lengths first (cdr pairs))))))
(defun sort-by-end (pairs)
(sort pairs '>' :key 'cadr))
(defun last-endpoint (pairs)
(cadr (car (sort-by-end pairs))))
(defun gap-distance (p1 p2)
(if (< (cadr p1) (car p2))
(- (car p2) (cadr p1))
0))
(defun sort-pairs (pairs)
(let ((swapped (swap-pairs pairs)))
(sort swapped '< :key 'car)))
(defun swap-pairs (pairs)
(let ((result-list nil))
(dolist (pair pairs)
(if (< (cadr pair) (car pair))
(push (list (cadr pair) (car pair)) result-list)
(push pair result-list)))
result-list))
;;
;;
;; Detect lines within the bounding region around the
;; grouping line. Transform the lines to a local coordinate
;; system (local to grouping line) by projecting the
;; detected lines onto the grouping line.
;;
;; These lines can then be summed along their length for
;; support information.
(defun supporting-line-begin-end-pairs (image u1 v1 u2 v2 width)
(let* ((result-line-list nil)
(linelist (clip-lines-to-quad
(local-intensity-edges image u1 v1 u2 v2 width)
u1 v1 u2 v2 width)))
(dolist (line linelist)
(push (project-line-1d u1 v1 u2 v2 line) result-line-list))
result-line-list))
;;
;; Project line endpoints of 'line' onto the 1D line (u1 v1 u2 v2)
;; the result for each point is a positive 1D scalar that represents
;; the distance along the cooordinate line. (b1 e1)
;;
(defun project-line-1d (u1 v1 u2 v2 line)
(let* ((basevec (unit-vector-2d (make-vec-2d u1 v1 u2 v2)))
(vec1 (make-vec-2d u1 v1 (car line) (cadr line)))
(vec2 (make-vec-2d u1 v1 (third line) (fourth line)))
(cos1 (cos-angle-2d basevec vec1))
(cos2 (cos-angle-2d basevec vec2))
(b (* cos1 (linear-algebra::vector-length vec1)))
(e (* cos2 (linear-algebra::vector-length vec2))))
(list b e)))
(defun project-line (u1 v1 u2 v2 line)
(let* ((basevec (unit-vector-2d (make-vec-2d u1 v1 u2 v2)))
(vec1 (make-vec-2d u1 v1 (car line) (cadr line)))
(vec2 (make-vec-2d u1 v1 (third line) (fourth line)))
(cos1 (cos-angle-2d basevec vec1))
(cos2 (cos-angle-2d basevec vec2))
(len1 (* cos1 (linear-algebra::vector-length vec1)))
(len2 (* cos2 (linear-algebra::vector-length vec2))))
(list (+ u1 (* (car basevec) len1)) (+ v1 (* (cadr basevec) len1))
(+ u1 (* (car basevec) len2)) (+ v1 (* (cadr basevec) len2)))))
(defun unit-vector-2d (vec)
(let ((len (linear-algebra::vector-length vec)))
(list (/ (car vec) len) (/ (cadr vec) len))))
(defun line-length (line)
(let ((vec (make-vec-2d (car line) (cadr line) (third line) (fourth line))))
(linear-algebra::vector-length vec)))
;;
;; Return the local intensity edge list for the bounding box around
;; u1 v1 and u2 v2.
;;
;;
;; Note: The variable *topdown-edgels-for-bdetect* has been initalized
;; by the "compute-2dworld-canny-edges" routine for the entire
;; bounding box;
;; C. Jaynes (Aug. 11)
;;
(defun local-intensity-edges (image u1 v1 u2 v2 width)
(let* ((startx (- (min u1 u2) width))
(starty (- (min v1 v2) width))
(stopx (+ (max u1 u2) width))
(stopy (+ (max v1 v2) width)))
;; (edges (compute-2dworld-canny-edges image startx starty
;; stopx stopy)))
(find-oriented-2dworld-lines *topdown-edgels-for-bdetect*
(compute-angle u1 v1 u2 v2) startx starty stopx stopy)))
;;
;; Sort lines from min->max values of
;;
;;
;;
(defun compute-angle (u1 v1 u2 v2)
(let ((xaxis (make-vec-2d 0.0 0.0 1.0 0.0)))
(if (< u1 u2)
(degrees (acos (cos-angle-2d
(make-vec-2d u1 v1 u2 v2) xaxis)))
(degrees (acos (cos-angle-2d
(make-vec-2d u2 v2 u1 v1) xaxis))))))
;;
;;
;; CLIP LINES TO ORIENTED QUAD.
;;
(defun clip-lines-to-quad (lines u1 v1 u2 v2 width)
(multiple-value-bind (box1 box2 box3 box4)
(compute-bounding-quad u1 v1 u2 v2 width)
(clip-function lines box1 box2 box3 box4)))
(defun compute-bounding-quad (u1 v1 u2 v2 width)
(let* ((r1 (perp-line-point u1 v1 u2 v2 u1 v1 width))
(r2 (perp-line-point u1 v1 u2 v2 u2 v2 width))
(r3 (perp-line-point u1 v1 u2 v2 u2 v2
(- width)))
(r4 (perp-line-point u1 v1 u2 v2 u1 v1 (- width))))
(values r1 r2 r3 r4)))
(defun perp-line-point (u1 v1 u2 v2 x y dist)
(multiple-value-bind (px py)
(snakes::perpendicular-from-point-on-line u1 v1 u2 v2 x y dist)
(list px py)))
(defun clip-function (list-of-lines pt1 pt2 pt3 pt4)
(let ((result-line-list nil))
(multiple-value-bind (l1 l2 l3 l4)
(epi::clip-to-quad-init pt1 pt2 pt3 pt4)
(dolist (line list-of-lines)
(multiple-value-bind (x1 y1 x2 y2 ok)
(epi::clip-to-quad (car line) (cadr line) (third line) (fourth line)
l1 l2 l3 l4)
(when ok
(push (list x1 y1 x2 y2) result-line-list)))))
result-line-list))