cmcongrid.pro
6.36 KB
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
; $Id: cmcongrid.pro,v 1.3 2007/03/29 13:52:20 craigm Exp $
;+
; NAME:
; CMCONGRID
;
; PURPOSE:
; Shrink or expand the size of an array by an arbitrary amount.
; This IDL procedure simulates the action of the VAX/VMS
; CONGRID/CONGRIDI function.
;
; This function is similar to "REBIN" in that it can resize a
; one, two, or three dimensional array. "REBIN", however,
; requires that the new array size must be an integer multiple
; of the original size. CONGRID will resize an array to any
; arbitrary size (REBIN is somewhat faster, however).
; REBIN averages multiple points when shrinking an array,
; while CONGRID just resamples the array.
;
; CATEGORY:
; Array Manipulation.
;
; CALLING SEQUENCE:
; array = CONGRID(array, x, y, z)
;
; INPUTS:
; array: A 1, 2, or 3 dimensional array to resize.
; Data Type : Any type except string or structure.
;
; x: The new X dimension of the resized array.
; Data Type : Int or Long (greater than or equal to 2).
;
; OPTIONAL INPUTS:
; y: The new Y dimension of the resized array. If the original
; array has only 1 dimension then y is ignored. If the
; original array has 2 or 3 dimensions then y MUST be present.
;
; z: The new Z dimension of the resized array. If the original
; array has only 1 or 2 dimensions then z is ignored. If the
; original array has 3 dimensions then z MUST be present.
;
; KEYWORD PARAMETERS:
; INTERP: If set, causes linear interpolation to be used.
; Otherwise, the nearest-neighbor method is used.
;
; CUBIC: If set, uses "Cubic convolution" interpolation. A more
; accurate, but more time-consuming, form of interpolation.
; CUBIC has no effect when used with 3 dimensional arrays.
;
; MINUS_ONE:
; If set, will prevent CONGRID from extrapolating one row or
; column beyond the bounds of the input array. For example,
; If the input array has the dimensions (i, j) and the
; output array has the dimensions (x, y), then by
; default the array is resampled by a factor of (i/x)
; in the X direction and (j/y) in the Y direction.
; If MINUS_ONE is present (AND IS NON-ZERO) then the array
; will be resampled by the factors (i-1)/(x-1) and
; (j-1)/(y-1).
;
; HALF_HALF:
; If set, will tell CONGRID to extrapolate a *half* row
; and column on either side, rather than the default of
; one full row/column at the ends of the array. If you
; are interpolating images with few rows, then the
; output will be more consistent with this technique.
; This keyword is intended as a replacement for
; MINUS_ONE, and both keywords probably should not be
; used in the same call to CONGRID.
;
; OUTPUTS:
; The returned array has the same number of dimensions as the original
; array and is of the same data type. The returned array will have
; the dimensions (x), (x, y), or (x, y, z) depending on how many
; dimensions the input array had.
;
; PROCEDURE:
; IF the input array has three dimensions, or if INTERP is set,
; then the IDL interpolate function is used to interpolate the
; data values.
; If the input array has two dimensions, and INTERP is NOT set,
; then the IDL POLY_2D function is used for nearest neighbor sampling.
; If the input array has one dimension, and INTERP is NOT set,
; then nearest neighbor sampling is used.
;
; EXAMPLE:
; ; vol is a 3-D array with the dimensions (80, 100, 57)
; ; Resize vol to be a (90, 90, 80) array
; vol = CONGRID(vol, 90, 90, 80)
;
; MODIFICATION HISTORY:
; DMS, Sept. 1988.
; DMS, Added the MINUS_ONE keyword, Sept. 1992.
; Daniel Carr. Re-wrote to handle one and three dimensional arrays
; using INTERPOLATE function.
; DMS, RSI, Nov, 1993. Added CUBIC keyword.
; Craig Markwardt, Dec, 1997. Added halfhalf keyword to
; more evenly distribute "dead" pixel row
; Use uniformly spaced grid points for half_half W. Landsman Feb. 2000
; (and slightly modified by C. Markwardt 14 Feb 2000)
; Fix in case where INTERP=0 (nearest neighbor interp) and
; expanding the image (thanks to Larry Bradley) 28 Mar 2007
;
; $Id: cmcongrid.pro,v 1.3 2007/03/29 13:52:20 craigm Exp $
;-
FUNCTION CMCONGRID, arr, x, y, z, Interp=int, Minus_One=m1, Cubic = cubic, $
Half_Half=hh
ON_ERROR, 2 ;Return to caller if error
s = Size(arr)
IF ((s(0) EQ 0) OR (s(0) GT 3)) THEN $
Message, 'Array must have 1, 2, or 3 dimensions.'
; Supply defaults = no interpolate, and no minus_one.
if n_elements(int) le 0 then int = 0 else int = keyword_set(int)
if n_elements(m1) le 0 then m1 = 0 else m1 = keyword_set(m1)
; Compute offsets pixel offsets for half_half
halfx = 0.0 & halfy = 0.0 & halfz = 0.0
if keyword_set(hh) then begin
if s(0) GE 1 then halfx = -0.5 + (float(s(1))/x)
if s(0) GE 2 then halfy = -0.5 + (float(s(2))/y)
if s(0) GE 3 then halfz = -0.5 + (float(s(3))/z)
endif
cub = KEYWORD_SET(cubic)
if cub THEN int = 1 ;Cubic implies interpolate
CASE s(0) OF
1: BEGIN ; *** ONE DIMENSIONAL ARRAY
srx = float(s(1) - m1)/(x-m1) * findgen(x) + halfx
IF int THEN $
RETURN, INTERPOLATE(arr, srx, CUBIC = cub) ELSE $
RETURN, arr(ROUND(srx))
ENDCASE
2: BEGIN ; *** TWO DIMENSIONAL ARRAY
IF int THEN BEGIN
srx = float(s(1) - m1) / (x-m1) * findgen(x) + halfx
sry = float(s(2) - m1) / (y-m1) * findgen(y) + halfy
RETURN, INTERPOLATE(arr, srx, sry, /GRID, CUBIC=cub)
ENDIF ELSE BEGIN
;; match IDL's CONGRID function
expand = (x gt s[1])
xm1 = (m1 or expand) ? x-1 : x
RETURN, POLY_2D(arr, $
[[0,0],[(s(1)-m1)/float(xm1),0]], $ ;Use poly_2d
[[0,(s(2)-m1)/float(y-m1)],[0,0]],int,x,y)
ENDELSE
ENDCASE
3: BEGIN ; *** THREE DIMENSIONAL ARRAY
srx = float(s(1) - m1) / (x-m1) * findgen(x) + halfx
sry = float(s(2) - m1) / (y-m1) * findgen(y) + halfy
srz = float(s(3) - m1) / (z-m1) * findgen(z) + halfz
RETURN, interpolate(arr, srx, sry, srz, /grid)
ENDCASE
ENDCASE
RETURN, arr_r
END