src/Translate.jl

changeset 0
eef71dd7202b
child 2
684032c29023
equal deleted inserted replaced
-1:000000000000 0:eef71dd7202b
1 ######################################
2 # Image subpixel accuracy translation
3 ######################################
4
5 module Translate
6
7 ##########
8 # Exports
9 ##########
10
11 export interpolate2d,
12 interpolate2d_quadrants,
13 extract_subimage!,
14 translate_image!,
15 DisplacementFull,
16 DisplacementConstant,
17 Displacement,
18 Image
19
20 ##################
21 # Types
22 ##################
23
24 # Two different types of displacement data supported:
25 # a) given in each pixel
26 # b) constant in space
27 Image = Array{Float64,2}
28 DisplacementFull = Array{Float64,3}
29 DisplacementConstant = Array{Float64,1}
30 Displacement = Union{DisplacementFull,DisplacementConstant}
31
32 #############################
33 # Base interpolation routine
34 #############################
35
36 @inline function interpolate2d_quadrants(v, (x, y))
37 (m, n) = size(v)
38 clipx = xʹ -> max(1, min(xʹ, m))
39 clipy = yʹ -> max(1, min(yʹ, n))
40
41 xfℤ = clipx(floor(Int, x))
42 xcℤ = clipx(ceil(Int, x))
43 yfℤ = clipy(floor(Int, y))
44 ycℤ = clipy(ceil(Int, y))
45
46 xf = convert(Float64, xfℤ)
47 xc = convert(Float64, xcℤ)
48 yf = convert(Float64, yfℤ)
49 yc = convert(Float64, ycℤ)
50 xm = (xf+xc)/2
51 ym = (yf+yc)/2
52
53 vff = @inbounds v[xfℤ, yfℤ]
54 vfc = @inbounds v[xfℤ, ycℤ]
55 vcf = @inbounds v[xcℤ, yfℤ]
56 vcc = @inbounds v[xcℤ, ycℤ]
57 vmm = (vff+vfc+vcf+vcc)/4
58
59 if xfℤ==xcℤ
60 if yfℤ==ycℤ
61 # Completely degenerate case
62 v = vmm
63 else
64 # Degenerate x
65 v = vff+(y-yf)/(yc-yf)*(vfc-vff)
66 end
67 elseif yfℤ==ycℤ
68 # Degenerate y
69 v = vff + (x-xf)/(xc-xf)*(vcf-vff)
70 elseif y-ym ≥ x-xm
71 # top-left half
72 if (y-ym) + (x-xm) ≥ 0
73 # top quadrant
74 v = vfc + (x-xf)/(xc-xf)*(vcc-vfc) + (y-yc)/(ym-yc)*(vmm-(vcc+vfc)/2)
75 else
76 # left quadrant
77 v = vff + (y-yf)/(yc-yf)*(vfc-vff) + (x-xf)/(xm-xf)*(vmm-(vfc+vff)/2)
78 end
79 else
80 # bottom-left half
81 if (y-ym) + (x-xm) ≥ 0
82 # right quadrant
83 v = vcf + (y-yf)/(yc-yf)*(vcc-vcf) + (x-xc)/(xm-xc)*(vmm-(vcc+vcf)/2)
84 else
85 # bottom quadrant
86 v = vff + (x-xf)/(xc-xf)*(vcf-vff) + (y-yf)/(ym-yf)*(vmm-(vcf+vff)/2)
87 end
88 end
89
90 return v
91 end
92
93 interpolate2d = interpolate2d_quadrants
94
95 ##############
96 # Translation
97 ##############
98
99 @polly function translate_image!(x, z, u::DisplacementFull)
100 @assert(size(u, 1)==2 && size(x)==size(u)[2:end] && size(x)==size(z))
101
102 @inbounds @simd for i=1:size(x, 1)
103 @simd for j=1:size(x, 2)
104 pt = (i - u[1, i, j], j - u[2, i, j])
105 x[i, j] = interpolate2d(z, pt)
106 end
107 end
108 end
109
110 @polly function translate_image!(x, z, u::DisplacementConstant)
111 @assert(size(u)==(2,) && size(x)==size(z))
112
113 @inbounds @simd for i=1:size(x, 1)
114 @simd for j=1:size(x, 2)
115 pt = (i - u[1], j - u[2])
116 x[i, j] = interpolate2d(z, pt)
117 end
118 end
119 end
120
121 ######################
122 # Subimage extraction
123 ######################
124
125 @polly function extract_subimage!(b, im, v::DisplacementConstant)
126 (imx, imy) = size(im)
127 (bx, by) = size(b)
128
129 # Translation from target to source coordinates
130 vxʹ = v[1] + (imx-bx)/2
131 vyʹ = v[2] + (imy-by)/2
132
133 # Target image indices within source image
134 px = ceil(Int, max(1, vxʹ + 1) - vxʹ)
135 py = ceil(Int, max(1, vyʹ + 1) - vyʹ)
136 qx = floor(Int, min(imx, vxʹ + bx) - vxʹ)
137 qy = floor(Int, min(imy, vyʹ + by) - vyʹ)
138
139 b .= 0
140
141 @inbounds @simd for i=px:qx
142 for j=py:qy
143 b[i, j] = interpolate2d(im, (i+vxʹ, j+vyʹ))
144 end
145 end
146 end
147
148 end

mercurial