source: trunk/SRC/Interpolation/square2quadrilateral.pro

Last change on this file was 495, checked in by pinsard, 10 years ago

fix thanks to coding rules; typo; dupe empty lines; trailing blanks

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