Tue, 25 Aug 2020 14:04:06 +0300
Make denoise test script a proper project so it can be run easily.
0 | 1 | ###################################### |
2 | # Image subpixel accuracy translation | |
3 | ###################################### | |
4 | ||
7
ab7d59b47140
Add __precompile__() for whatever it is worth
Tuomo Valkonen <tuomov@iki.fi>
parents:
6
diff
changeset
|
5 | __precompile__() |
ab7d59b47140
Add __precompile__() for whatever it is worth
Tuomo Valkonen <tuomov@iki.fi>
parents:
6
diff
changeset
|
6 | |
0 | 7 | module Translate |
8 | ||
32 | 9 | using AlgTools.Util: @threadsif |
10 | ||
0 | 11 | ########## |
12 | # Exports | |
13 | ########## | |
14 | ||
15 | export interpolate2d, | |
16 | interpolate2d_quadrants, | |
17 | extract_subimage!, | |
18 | translate_image!, | |
19 | DisplacementFull, | |
20 | DisplacementConstant, | |
21 | Displacement, | |
22 | Image | |
23 | ||
24 | ################## | |
25 | # Types | |
26 | ################## | |
27 | ||
28 | # Two different types of displacement data supported: | |
29 | # a) given in each pixel | |
30 | # b) constant in space | |
31 | Image = Array{Float64,2} | |
32 | DisplacementFull = Array{Float64,3} | |
33 | DisplacementConstant = Array{Float64,1} | |
34 | Displacement = Union{DisplacementFull,DisplacementConstant} | |
35 | ||
36 | ############################# | |
37 | # Base interpolation routine | |
38 | ############################# | |
39 | ||
31
62645d05985a
Potentially optimise a tuple creation away
Tuomo Valkonen <tuomov@iki.fi>
parents:
30
diff
changeset
|
40 | @inline function interpolate2d_quadrants(v, x, y) |
0 | 41 | (m, n) = size(v) |
42 | clipx = xʹ -> max(1, min(xʹ, m)) | |
43 | clipy = yʹ -> max(1, min(yʹ, n)) | |
44 | ||
45 | xfℤ = clipx(floor(Int, x)) | |
46 | xcℤ = clipx(ceil(Int, x)) | |
47 | yfℤ = clipy(floor(Int, y)) | |
48 | ycℤ = clipy(ceil(Int, y)) | |
49 | ||
50 | xf = convert(Float64, xfℤ) | |
51 | xc = convert(Float64, xcℤ) | |
52 | yf = convert(Float64, yfℤ) | |
53 | yc = convert(Float64, ycℤ) | |
54 | xm = (xf+xc)/2 | |
55 | ym = (yf+yc)/2 | |
56 | ||
57 | vff = @inbounds v[xfℤ, yfℤ] | |
58 | vfc = @inbounds v[xfℤ, ycℤ] | |
59 | vcf = @inbounds v[xcℤ, yfℤ] | |
60 | vcc = @inbounds v[xcℤ, ycℤ] | |
61 | vmm = (vff+vfc+vcf+vcc)/4 | |
62 | ||
63 | if xfℤ==xcℤ | |
64 | if yfℤ==ycℤ | |
65 | # Completely degenerate case | |
66 | v = vmm | |
67 | else | |
68 | # Degenerate x | |
69 | v = vff+(y-yf)/(yc-yf)*(vfc-vff) | |
70 | end | |
71 | elseif yfℤ==ycℤ | |
72 | # Degenerate y | |
73 | v = vff + (x-xf)/(xc-xf)*(vcf-vff) | |
74 | elseif y-ym ≥ x-xm | |
75 | # top-left half | |
76 | if (y-ym) + (x-xm) ≥ 0 | |
77 | # top quadrant | |
78 | v = vfc + (x-xf)/(xc-xf)*(vcc-vfc) + (y-yc)/(ym-yc)*(vmm-(vcc+vfc)/2) | |
79 | else | |
80 | # left quadrant | |
81 | v = vff + (y-yf)/(yc-yf)*(vfc-vff) + (x-xf)/(xm-xf)*(vmm-(vfc+vff)/2) | |
82 | end | |
83 | else | |
84 | # bottom-left half | |
85 | if (y-ym) + (x-xm) ≥ 0 | |
86 | # right quadrant | |
87 | v = vcf + (y-yf)/(yc-yf)*(vcc-vcf) + (x-xc)/(xm-xc)*(vmm-(vcc+vcf)/2) | |
88 | else | |
89 | # bottom quadrant | |
90 | v = vff + (x-xf)/(xc-xf)*(vcf-vff) + (y-yf)/(ym-yf)*(vmm-(vcf+vff)/2) | |
91 | end | |
92 | end | |
93 | ||
94 | return v | |
95 | end | |
96 | ||
97 | ############## | |
98 | # Translation | |
99 | ############## | |
100 | ||
32 | 101 | function translate_image!(x, z, u::DisplacementFull; |
102 | threads::Bool=false) | |
0 | 103 | @assert(size(u, 1)==2 && size(x)==size(u)[2:end] && size(x)==size(z)) |
104 | ||
32 | 105 | @threadsif threads for i=1:size(x, 1) |
106 | for j=1:size(x, 2) | |
31
62645d05985a
Potentially optimise a tuple creation away
Tuomo Valkonen <tuomov@iki.fi>
parents:
30
diff
changeset
|
107 | x[i, j] = interpolate2d_quadrants(z, i - u[1, i, j], j - u[2, i, j]) |
0 | 108 | end |
109 | end | |
110 | end | |
111 | ||
32 | 112 | function translate_image!(x, z, u::DisplacementConstant; |
113 | threads::Bool=false) | |
0 | 114 | @assert(size(u)==(2,) && size(x)==size(z)) |
115 | ||
30
0b25d9ef7af9
Better @inbounds placements etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
29
diff
changeset
|
116 | @inbounds a, b = u[1], u[2] |
20 | 117 | |
32 | 118 | @threadsif threads for i=1:size(x, 1) |
119 | for j=1:size(x, 2) | |
31
62645d05985a
Potentially optimise a tuple creation away
Tuomo Valkonen <tuomov@iki.fi>
parents:
30
diff
changeset
|
120 | x[i, j] = interpolate2d_quadrants(z, i - a, j - b) |
0 | 121 | end |
122 | end | |
123 | end | |
124 | ||
125 | ###################### | |
126 | # Subimage extraction | |
127 | ###################### | |
128 | ||
32 | 129 | function extract_subimage!(b, im, v::DisplacementConstant; |
130 | threads::Bool=false) | |
0 | 131 | (imx, imy) = size(im) |
132 | (bx, by) = size(b) | |
133 | ||
134 | # Translation from target to source coordinates | |
2 | 135 | vxʹ = (imx-bx)/2 - v[1] |
136 | vyʹ = (imy-by)/2 - v[2] | |
0 | 137 | |
138 | # Target image indices within source image | |
29 | 139 | px = min(max(ceil(Int, max(1, vxʹ + 1) - vxʹ), 1), bx) |
140 | py = min(max(ceil(Int, max(1, vyʹ + 1) - vyʹ), 1), by) | |
141 | qx = max(min(floor(Int, min(imx, vxʹ + bx) - vxʹ), bx), 1) | |
142 | qy = max(min(floor(Int, min(imy, vyʹ + by) - vyʹ), by), 1) | |
0 | 143 | |
20 | 144 | @inbounds begin |
145 | b[1:px-1, :] .= 0 | |
29 | 146 | b[qx+1:bx, :] .= 0 |
30
0b25d9ef7af9
Better @inbounds placements etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
29
diff
changeset
|
147 | end |
0 | 148 | |
32 | 149 | @threadsif false for i=px:qx |
30
0b25d9ef7af9
Better @inbounds placements etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
29
diff
changeset
|
150 | @inbounds begin |
20 | 151 | b[i, 1:py-1] .= 0 |
29 | 152 | b[i, qy+1:by] .= 0 |
30
0b25d9ef7af9
Better @inbounds placements etc.
Tuomo Valkonen <tuomov@iki.fi>
parents:
29
diff
changeset
|
153 | for j=py:qy |
31
62645d05985a
Potentially optimise a tuple creation away
Tuomo Valkonen <tuomov@iki.fi>
parents:
30
diff
changeset
|
154 | b[i, j] = interpolate2d_quadrants(im, i+vxʹ, j+vyʹ) |
20 | 155 | end |
0 | 156 | end |
157 | end | |
158 | end | |
159 | ||
5
29b38780d52b
Add precompilation hints. Do they help or not?
Tuomo Valkonen <tuomov@iki.fi>
parents:
2
diff
changeset
|
160 | ##################################################### |
29b38780d52b
Add precompilation hints. Do they help or not?
Tuomo Valkonen <tuomov@iki.fi>
parents:
2
diff
changeset
|
161 | # Precompilation hints to speed up compilation time |
29b38780d52b
Add precompilation hints. Do they help or not?
Tuomo Valkonen <tuomov@iki.fi>
parents:
2
diff
changeset
|
162 | # for projects depending on this package (hopefully). |
29b38780d52b
Add precompilation hints. Do they help or not?
Tuomo Valkonen <tuomov@iki.fi>
parents:
2
diff
changeset
|
163 | ###################################################### |
29b38780d52b
Add precompilation hints. Do they help or not?
Tuomo Valkonen <tuomov@iki.fi>
parents:
2
diff
changeset
|
164 | |
29b38780d52b
Add precompilation hints. Do they help or not?
Tuomo Valkonen <tuomov@iki.fi>
parents:
2
diff
changeset
|
165 | precompile(translate_image!, (Array{Float64,2}, Array{Float64,2}, Array{Float64,1})) |
29b38780d52b
Add precompilation hints. Do they help or not?
Tuomo Valkonen <tuomov@iki.fi>
parents:
2
diff
changeset
|
166 | precompile(translate_image!, (Array{Float64,2}, Array{Float64,2}, Array{Float64,3})) |
29b38780d52b
Add precompilation hints. Do they help or not?
Tuomo Valkonen <tuomov@iki.fi>
parents:
2
diff
changeset
|
167 | precompile(extract_subimage!, (Array{Float64,2}, Array{Float64,2}, Array{Float64,1})) |
29b38780d52b
Add precompilation hints. Do they help or not?
Tuomo Valkonen <tuomov@iki.fi>
parents:
2
diff
changeset
|
168 | |
0 | 169 | end |