source: trunk/SRC/Interpolation/square2quadrilateral.pro @ 138

Last change on this file since 138 was 136, checked in by pinsard, 18 years ago

some improvements and corrections in some .pro file according to
aspell and idldoc log file

  • Property svn:keywords set to Id
File size: 5.5 KB
Line 
1;+
2;
3; @file_comments
4; warm (or map) a unit square onto an arbitrary quadrilateral
5; according to the 4-point correspondences:
6;       (0,0) -> (x0,y0)
7;       (1,0) -> (x1,y1)
8;       (1,1) -> (x2,y2)
9;       (0,1) -> (x3,y3)
10; The mapping is done using perspective transformation which preserve
11; lines in all orientations and permit quadrilateral to quadrilateral
12; mappings. see ref. bellow.
13;
14; @categories image, grid manipulation
15;
16; @param x0in {in}{required}
17; @param y0in {in}{required}
18; @param x1in {in}{required}
19; @param y1in {in}{required}
20; @param x2in {in}{required}
21; @param y2in {in}{required}
22; @param x3in {in}{required}
23; @param y3in {in}{required}
24; the coordinates of the quadrilateral (see above for correspondance with the
25; unit square).
26; Can be scalar or array.
27; (x0,y0), (x1,y1), (x2,y2) and (x3,y3) are given in the anticlockwise order.
28;
29;
30; @param xxin {in}{optional}
31; @param yyin {in}{optional}
32; the coordinates of the point(s) for which we want to do the mapping.
33;
34; @returns
35; (2,n) array: the new coodinates (xout, yout) of the (xin,yin)
36; point(s) after mapping.
37; If xin is a scalar, then n is equal to the number of elements of
38; x0. If xin is an array , then n is equal to the number of
39; elements of xin.
40; If xin and yin are omited, square2quadrilateral returns the
41; matrix A which is used for the inverse transformation.
42;
43; @restrictions
44; I think degenerated quadrilateral (e.g. flat of twisted) is not work.
45; This has to be tested.
46;
47; @examples
48;
49; IDL> splot,[0,5],[0,3],/nodata,xstyle=1,ystyle=1
50; IDL> tracegrille, findgen(11)*.1, findgen(11)*.1,color=indgen(12)*20
51; IDL> xin = (findgen(11)*.1)#replicate(1, 11)
52; IDL> yin = replicate(1, 11)#(findgen(11)*.1)
53; IDL> out = square2quadrilateral(2,1,3,0,5,1,2,3, xin, yin)
54; IDL> tracegrille, reform(out[0,*],11,11), reform(out[1,*],11,11),color=indgen(12)*20
55;
56; @history
57;      Sebastien Masson (smasson\@lodyc.jussieu.fr)
58;      August 2003
59;      Based on "Digital Image Warping" by G. Wolberg
60;      IEEE Computer Society Press, Los Alamitos, California
61;      Chapter 3, see p 52-56
62;
63;
64; @version $Id$
65;
66;-
67;------------------------------------------------------------
68;------------------------------------------------------------
69;------------------------------------------------------------
70FUNCTION square2quadrilateral, x0in, y0in, x1in, y1in, x2in, y2in, x3in, y3in, xxin, yyin
71;
72; Warning, wrong definition of (x2,y2) and (x3,y3) at the bottom of
73; page 54 of Wolberg's book, see figure 3.7 page 56 for the good
74; definition.
75;
76;
77  compile_opt idl2, strictarrsubs
78;
79  IF keyword_set(double) THEN BEGIN
80    x0 = double(x0in)
81    x1 = double(x1in)
82    x2 = double(x2in)
83    x3 = double(x3in)
84    y0 = double(y0in)
85    y1 = double(y1in)
86    y2 = double(y2in)
87    y3 = double(y3in)
88    IF arg_present(xxin) THEN BEGIN
89      xin = double(xxin)
90      yin = double(yyin)
91    ENDIF
92  ENDIF ELSE BEGIN
93    x0 = float(x0in)
94    x1 = float(x1in)
95    x2 = float(x2in)
96    x3 = float(x3in)
97    y0 = float(y0in)
98    y1 = float(y1in)
99    y2 = float(y2in)
100    y3 = float(y3in)
101    IF arg_present(xxin) THEN BEGIN
102      xin = float(xxin)
103      yin = float(yyin)
104    ENDIF
105  ENDELSE
106;
107  IF keyword_set(double) THEN a = dblarr(8, n_elements(x0)) $
108  ELSE a = fltarr(8, n_elements(x0))
109;
110  delx3 = x0-x1+x2-x3
111  dely3 = y0-y1+y2-y3
112;
113  affinemap = where(delx3 EQ 0 AND dely3 EQ 0)
114  IF affinemap[0] NE -1 THEN BEGIN
115    xx0 = x0[affinemap]
116    xx1 = x1[affinemap]
117    xx2 = x2[affinemap]
118    yy0 = y0[affinemap]
119    yy1 = y1[affinemap]
120    yy2 = y2[affinemap]
121;
122    a[0, affinemap] = xx1-xx0
123    a[1, affinemap] = xx2-xx1
124    a[2, affinemap] = xx0
125    a[3, affinemap] = yy1-yy0
126    a[4, affinemap] = yy2-yy1
127    a[5, affinemap] = yy0
128    a[6, affinemap] = 0
129    a[7, affinemap] = 0
130  ENDIF
131;
132  projectivemap = where(delx3 NE 0 OR dely3 NE 0)
133  IF projectivemap[0] NE -1 THEN BEGIN
134    xx0 = x0[projectivemap]
135    xx1 = x1[projectivemap]
136    xx2 = x2[projectivemap]
137    xx3 = x3[projectivemap]
138    yy0 = y0[projectivemap]
139    yy1 = y1[projectivemap]
140    yy2 = y2[projectivemap]
141    yy3 = y3[projectivemap]
142;
143    delx1 = xx1-xx2
144    dely1 = yy1-yy2
145    delx2 = xx3-xx2
146    dely2 = yy3-yy2
147    delx3 = delx3[projectivemap]
148    dely3 = dely3[projectivemap]
149;
150    div = delx1*dely2-dely1*delx2
151    zero = where(div EQ 0)
152    IF zero[0] NE -1 THEN BEGIN
153      stop
154    ENDIF
155    a13 = (delx3*dely2-dely3*delx2)/div
156    a23 = (delx1*dely3-dely1*delx3)/div
157;
158    a[0, projectivemap] = xx1-xx0+a13*xx1
159    a[1, projectivemap] = xx3-xx0+a23*xx3
160    a[2, projectivemap] = xx0
161    a[3, projectivemap] = yy1-yy0+a13*yy1
162    a[4, projectivemap] = yy3-yy0+a23*yy3
163    a[5, projectivemap] = yy0
164    a[6, projectivemap] = a13
165    a[7, projectivemap] = a23
166  ENDIF
167;
168  IF NOT arg_present(xxin) THEN return, a
169;
170  IF n_elements(xin) EQ 1 THEN BEGIN
171    xin = replicate(xin, n_elements(x0))
172    yin = replicate(yin, n_elements(x0))
173  ENDIF
174;
175  IF keyword_set(double) THEN res = dblarr(2, n_elements(xin)) $
176  ELSE res = fltarr(2, n_elements(xin))
177  IF n_elements(x0) EQ 1 THEN BEGIN
178    div = a[6]*xin[*] + a[7]*yin[*] + 1
179    zero = where(div EQ 0)
180    IF zero[0] NE -1 THEN BEGIN
181      stop
182    ENDIF
183    res[0, *] = (a[0]*xin[*] + a[1]*yin[*] + a[2])/div
184    res[1, *] = (a[3]*xin[*] + a[4]*yin[*] + a[5])/div
185  ENDIF ELSE BEGIN
186    div = a[6, *]*xin +a[7, *]*yin + 1
187    zero = where(div EQ 0)
188    IF zero[0] NE -1 THEN BEGIN
189      stop
190    ENDIF
191    res[0, *] = (a[0, *]*xin[*] + a[1, *]*yin[*] + a[2, *])/div
192    res[1, *] = (a[3, *]*xin[*] + a[4, *]*yin[*] + a[5, *])/div
193  ENDELSE
194;
195  RETURN, res
196END
Note: See TracBrowser for help on using the repository browser.