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

Last change on this file since 103 was 101, checked in by pinsard, 18 years ago

start to modify headers of Interpolation *.pro files for better idldoc output

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