File: correlation.l

package info (click to toggle)
euslisp 9.31%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 55,448 kB
  • sloc: ansic: 41,610; lisp: 3,339; makefile: 286; sh: 238; asm: 138; python: 53
file content (181 lines) | stat: -rw-r--r-- 6,202 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
;;;; correlation.l
;;;  motion tracking window based on image correlation
;;; (C)1994, Toshihiro Matsui, Electrotechnical Laboratory
;;;

;; (in-package "IMAGE")

(export '(tracking-window))

;; C-coded image correlation is called.
;; (image::image-correlation ref search x y size threshold)
;; Image-correlation computes correlation value of 'ref' image in 'search'
;; image. Correlation value becomes the least when two images match most
;; greatly. Image-correlation return the correlation value and the location
;; of the most-matching window. The search area is a square window designated
;;  by x,y and extending size dots both in x and y direction.

(defmethod pixel-image
 (:grab (x y &optional (sampling 2))
    (grabber::window self x y sampling))
  )

(defclass tracking-window :super pixel-image
	:slots (x-pos y-pos	; position of the track window in *whole-image
		x-vel y-vel	; velocity
		pattern-size	; the size of this window
		window-size	; search area size, twice as big as the pattern
		x-win y-win	; the position of the search area
		window		; pixel image of the search area
		window-margin	; offset of topleft from pattern to search window
		update threshold	; shrinked pattern window
		half-pattern
		correlation
        ))

(defmethod tracking-window
 (:grab (&optional (x x-pos) (y y-pos) (sampling 2))
	(send-super :grab x y sampling))
 (:window-rectangle (val)
    (grabber:rectangle x-win y-win
	(+ x-win window-size) (+ y-win window-size) val))
 (:rectangle (val)
    (grabber:rectangle x-pos y-pos
	(+ x-pos pattern-size) (+ y-pos pattern-size) val))
 )

(defmethod tracking-window 
 (:correlation () correlation)
 (:move (newx newy)
    (send self :rectangle 0)
    (setq x-pos newx y-pos newy x-vel 0 y-vel 0)
    (send self :rectangle 2)
    (send self :grab)
    self)
 (:track (display-window &optional (th))
    (if display-window (send self :window-rectangle 0))
    (setq th  (if th (* th pattern-size pattern-size) threshold))
    (setq x-win (min (- 320 window-size)
		     (max 0 (+ x-pos window-margin  x-vel ))))
    (setq y-win (min (- 240 window-size)
		     (max 0 (+ y-pos window-margin y-vel))))
    (send window :grab x-win y-win)
    (let ((cor (image::image-correlation window self
			0 0	; offset in the window
			(/ window-size 2)
			th))
	  newx newy)
      (if *debug* (print (car cor)))
      (cond (cor
		(send self :rectangle 0)	;erase
		(setq newx (+ x-win (second cor))
		      newy (+ y-win (third cor)))
		(setq x-vel (- newx x-pos) y-vel (- newy y-pos))
		(setq x-pos newx y-pos newy)
		;; update the pattern
		(if update (send self :grab x-pos y-pos))
		(if display-window
		    (send window :display display-window nil x-win y-win))
		(send display-window :rectangle x-pos y-pos pattern-size pattern-size)
		(send self :rectangle 2)
		(if display-window (send self :window-rectangle 7))
		(setq correlation (car cor)))
	   (t (format t ";lost-1 ~A ~%" self)	;; track failed
	      ;; do not update pattern if track failed.
	      ;; (if update (send self :grab x-pos y-pos))
	      nil))
	))
 (:search (display-window &optional th)
    (if display-window (send self :window-rectangle 0))
    (setq th  (if th (/ (* th pattern-size pattern-size) 3) (/ threshold 3)))
    (setq x-win (min (- 320 window-size)
		     (max 0 (+ x-pos window-margin x-vel (- pattern-size) ))))
    (setq y-win (min (- 240 window-size)
		     (max 0 (+ y-pos window-margin y-vel (- pattern-size)))))
    (send window :grab x-win y-win 4)
    (send self :halve half-pattern)
    (let ((cor (image::image-correlation window half-pattern
			0 0	; offset in the window
			(/ window-size 2)
			th))
	  newx newy)
      (if *debug* (print (car cor)))
      (cond (cor
		(send self :rectangle 0)	;erase
		(setq newx (+ x-win (* (second cor) 2))
		      newy (+ y-win (* (third cor) 2)))
		(setq x-vel (- newx x-pos) y-vel (- newy y-pos))
		(setq x-pos newx y-pos newy)
		;; update the pattern
		(if update (send self :grab x-pos y-pos))
		;;(if display
		;; (send window :display *viewsurface* nil x-win y-win))
		;(send *viewsurface* :rectangle x y pattern-size pattern-size)
		(send self :rectangle 2)
	        (setq x-win (min (- 320 window-size)
			     (max 0 (+ x-pos window-margin))))
	        (setq y-win (min (- 240 window-size)
			     (max 0 (+ y-pos window-margin ))))
		(if display-window (send self :window-rectangle 7))
		(car cor))
	   (t (format t ";lost-2 ~A ~%" self)
	      nil)
	)
    ) )
 (:track-and-search (flag &optional th)
    (unless (send self :track flag th)
	(send self :search flag th)))
 )

(defmethod tracking-window
 (:x () x-pos)
 (:y () y-pos)
 (:pos () (integer-vector x-pos y-pos))
 (:vel () (integer-vector x-vel y-vel))
 (:insidep (pos &aux (x (aref pos 0)) (y (aref pos 1)))
    (and (<= x-pos x) (<= y-pos y)
	 (<= x (+ x-pos pattern-size)) (<= y (+ y-pos pattern-size))))
 (:update (&optional (flag :get))
    (if (eq flag :get)
	update
	(setq update flag)))
 (:prin1 (strm &rest mesg)
    (send-super* :prin1 strm
	(format nil "at (~d,~d) ~s ~d" x-pos y-pos update threshold) mesg))
 (:init (x y size win-size)	;separate size into width and height
    (setq x-vel 0 y-vel 0 x-pos x y-pos y)
    (setq pattern-size size)
    (send-super :init size size)
    (setq window-size win-size)
    (setq window (instance pixel-image :init window-size window-size))
    (send window :xpicture)
    (setq half-pattern (instance pixel-image :init (/ size 2) (/ size 2)))
    (setq window-margin (/ (- size window-size) 2))
    (setq x-win x-pos y-win y-pos)
    (setq update t)
    (setq threshold (* size size 20))
    (send self :move x-pos y-pos)
    self)
 )

(defun track-one (display threshold tracking-windows)
      (snap)
      (send-all tracking-windows :track display threshold))

(defun search (win)
    (send win :search t))

(defun cor (display threshold &rest tracking)
   (grabber::clear-overlay)
   (while t (track-one display threshold tracking)) )



(defun rotate-pattern (pat ang)
   (let* ((width (send pat :width)) (height (send pat :height))
	  (width/2 (/ width 2))  (height/2 (/ height 2))
	  (rotpat (send pat :duplicate))
	  (i (- width/2)) (j (- height/2))
	  (rotmat (rotation-matrix ang))
	  )
      ()))