22 InvWarpedView(img, tinv, [indices]) -> wv
33
44Create a view of `img` that lazily transforms any given index `I`
5- passed to `wv[I]` to correspond to `img[inv(tinv)(I)]`. While
6- technically this approach is known as backward mode warping, note
7- that `InvWarpedView` is created by supplying the forward
8- transformation
5+ passed to `wv[I]` so that `wv[I] == img[inv(tinv)(I)]`.
96
107The conceptual difference to [`WarpedView`](@ref) is that
118`InvWarpedView` is intended to be used when reasoning about the
@@ -14,20 +11,18 @@ Furthermore, `InvWarpedView` allows simple nesting of
1411transformations, in which case the transformations will be
1512composed into a single one.
1613
17- The optional parameter `indices` can be used to specify the
18- domain of the resulting `wv`. By default the indices are computed
19- in such a way that `wv` contains all the original pixels in
20- `img`.
14+ See [`invwarpedview`](@ref) for a convenient constructor of `InvWarpedView`.
2115
22- see [`invwarpedview`](@ref) for more information.
16+ For detailed explaination of warp, associated arguments and parameters,
17+ please refer to [`warp`](@ref).
2318"""
2419struct InvWarpedView{T,N,A,F,I,FI<: Transformation ,E} <: AbstractArray{T,N}
2520 inner:: WarpedView{T,N,A,F,I,E}
2621 inverse:: FI
2722end
2823
2924function InvWarpedView (inner:: WarpedView{T,N,TA,F,I,E} ) where {T,N,TA,F,I,E}
30- tinv = inv (inner. transform)
25+ tinv = _round ( inv (inner. transform) )
3126 InvWarpedView {T,N,TA,F,I,typeof(tinv),E} (inner, tinv)
3227end
3328
@@ -67,78 +62,35 @@ function Base.showarg(io::IO, A::InvWarpedView, toplevel)
6762end
6863
6964"""
70- invwarpedview(img, tinv, [indices], [degree = Linear()], [fill = NaN] ) -> wv
65+ invwarpedview(img, tinv, [indices]; kwargs... ) -> wv
7166
7267Create a view of `img` that lazily transforms any given index `I`
73- passed to `wv[I]` to correspond to `img[inv(tinv)(I)]`. While
74- technically this approach is known as backward mode warping, note
75- that `InvWarpedView` is created by supplying the forward
76- transformation. The given transformation `tinv` must accept a
77- `SVector` as input and support `inv(tinv)`. A useful package to
78- create a wide variety of such transformations is
79- [CoordinateTransformations.jl](https://github.com/FugroRoames/CoordinateTransformations.jl).
80-
81- When invoking `wv[I]`, values for `img` must be reconstructed at
82- arbitrary locations `inv(tinv)(I)`. `InvWarpedView` serves as a
83- wrapper around [`WarpedView`](@ref) which takes care of
84- interpolation and extrapolation. The parameters `degree` and
85- `fill` can be used to specify the b-spline degree and the
86- extrapolation scheme respectively.
87-
88- The optional parameter `indices` can be used to specify the
89- domain of the resulting `wv`. By default the indices are computed
90- in such a way that `wv` contains all the original pixels in
91- `img`.
92- """
93- @inline invwarpedview (A:: AbstractArray , tinv:: Transformation , args... ) =
94- InvWarpedView (A, tinv, args... )
95-
96- function invwarpedview (
97- A:: AbstractArray{T} ,
98- tinv:: Transformation ,
99- degree:: Union{Linear,Constant} ,
100- fill:: FillType = _default_fill (T)) where T
101- invwarpedview (box_extrapolation (A, degree, fill), tinv)
102- end
68+ passed to `wv[I]` so that `wv[I] == img[inv(tinv)(I)]`.
10369
104- function invwarpedview (
105- A:: AbstractArray{T} ,
106- tinv:: Transformation ,
107- indices:: Tuple ,
108- degree:: Union{Linear,Constant} ,
109- fill:: FillType = _default_fill (T)) where T
110- invwarpedview (box_extrapolation (A, degree, fill), tinv, indices)
111- end
70+ Except for the lazy evaluation, the following two lines are equivalent:
11271
113- function invwarpedview (
114- A:: AbstractArray ,
115- tinv:: Transformation ,
116- fill:: FillType )
117- invwarpedview (A, tinv, Linear (), fill)
118- end
72+ ```julia
73+ warp(img, inv(tform), [indices]; kwargs...)
74+ invwarpedview(img, tform, [indices]; kwargs...)
75+ ```
11976
120- function invwarpedview (
121- A:: AbstractArray ,
122- tinv:: Transformation ,
123- indices:: Tuple ,
124- fill:: FillType )
125- invwarpedview (A, tinv, indices, Linear (), fill)
77+ For detailed explaination of warp, associated arguments and parameters,
78+ please refer to [`warp`](@ref).
79+ """
80+ function invwarpedview (A:: AbstractArray , tinv:: Transformation , indices:: Tuple = autorange (A, tinv); kwargs... )
81+ InvWarpedView (box_extrapolation (A; kwargs... ), tinv, indices)
12682end
12783
128- function invwarpedview (
129- inner_view :: SubArray{T,N,W,I} ,
130- tinv :: Transformation ) where {T,N,W <: InvWarpedView ,I <: Tuple{Vararg{AbstractUnitRange}} }
131- inner = parent (inner_view)
132- new_inner = InvWarpedView (inner , tinv, autorange (inner, tinv) )
133- inds = autorange (CartesianIndices (inner_view . indices), tinv)
134- view (new_inner, map (x -> IdentityRange ( first (x), last (x)), inds) ... )
84+ # For SubArray:
85+ # 1. We can exceed the boundary of SubArray by using its parent and thus trick Interpolations in
86+ # order to get better extrapolation result around the border. Otherwise it will just fill it.
87+ # 2. For default indices, we use `IdentityUnitRange`, which guarantees `r[i] == i`, to preserve the view indices.
88+ function invwarpedview (A :: SubArray , tinv:: Transformation ; kwargs ... )
89+ default_indices = map (IdentityUnitRange, autorange (CartesianIndices (A . indices), tinv) )
90+ invwarpedview (A, tinv, default_indices; kwargs ... )
13591end
136-
137- function invwarpedview (
138- inner_view:: SubArray{T,N,W,I} ,
139- tinv:: Transformation ,
140- indices:: Tuple ) where {T,N,W<: InvWarpedView ,I<: Tuple{Vararg{AbstractUnitRange}} }
141- inner = parent (inner_view)
92+ function invwarpedview (A:: SubArray , tinv:: Transformation , indices:: Tuple ; kwargs... )
93+ inner = parent (A)
14294 new_inner = InvWarpedView (inner, tinv, autorange (inner, tinv))
14395 view (new_inner, indices... )
14496end
0 commit comments