-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Streamline API for warp and WarpedView #24
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
1957490
refactor warp to be consistent with WarpedView
Evizero fccebb1
clean up WarpedView API and add warpedview
Evizero 1015bfd
refactor warp and WarpedView to proper backward mode
Evizero c257622
add ImageInTerminal style visual tests
Evizero 38bcb40
enable color on travis
Evizero 6a2d808
try to enable color on appveyor
Evizero e5e6ccb
add tests for warp helper functions
Evizero 28aa3f7
improve warp helper functions
Evizero 2bdbce4
prototype deprecation strategy
Evizero 106f2d0
work in a round of reviews
Evizero a2aa627
work in a round of reviews
Evizero b79619d
reintroduce WarpedView
Evizero a805cc3
add warp support for OneTo inds
Evizero fcf939c
finish warpedview tests
Evizero 5ca0028
add docstring for warpedview
Evizero 86d0afb
add docstring for invwarpedview
Evizero ad5cb02
fix 0.6 ambiguities
Evizero 1ae4634
work in a round of reviews
Evizero File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# FIXME: upstream https://github.com/JuliaGraphics/ColorVectorSpace.jl/issues/75 | ||
@inline _nan(::Type{HSV{Float16}}) = HSV{Float16}(NaN16,NaN16,NaN16) | ||
@inline _nan(::Type{HSV{Float32}}) = HSV{Float32}(NaN32,NaN32,NaN32) | ||
@inline _nan(::Type{HSV{Float64}}) = HSV{Float64}(NaN,NaN,NaN) | ||
@inline _nan{T}(::Type{T}) = nan(T) | ||
|
||
# The default values used by extrapolation for off-domain points | ||
@compat const FillType = Union{Number,Colorant,Flat,Periodic,Reflect} | ||
@compat const FloatLike{T<:AbstractFloat} = Union{T,AbstractGray{T}} | ||
@compat const FloatColorant{T<:AbstractFloat} = Colorant{T} | ||
@inline _default_fill{T<:FloatLike}(::Type{T}) = convert(T, NaN) | ||
@inline _default_fill{T<:FloatColorant}(::Type{T}) = _nan(T) | ||
@inline _default_fill{T}(::Type{T}) = zero(T) | ||
|
||
box_extrapolation(etp::AbstractExtrapolation) = etp | ||
|
||
function box_extrapolation{T}(itp::AbstractInterpolation{T}, fill::FillType = _default_fill(T)) | ||
etp = extrapolate(itp, fill) | ||
box_extrapolation(etp) | ||
end | ||
|
||
function box_extrapolation{T,N,D<:Union{Linear,Constant}}(parent::AbstractArray{T,N}, degree::D = Linear(), args...) | ||
itp = Interpolations.BSplineInterpolation{T,N,typeof(parent),BSpline{D},OnGrid,0}(parent) | ||
box_extrapolation(itp, args...) | ||
end | ||
|
||
function box_extrapolation{T,N}(parent::AbstractArray{T,N}, degree::Interpolations.Degree, args...) | ||
itp = interpolate(parent, BSpline(degree), OnGrid()) | ||
box_extrapolation(itp, args...) | ||
end | ||
|
||
function box_extrapolation(parent::AbstractArray, fill::FillType) | ||
box_extrapolation(parent, Linear(), fill) | ||
end | ||
|
||
function box_extrapolation(itp::AbstractInterpolation, degree::Union{Linear,Constant}, args...) | ||
throw(ArgumentError("Boxing an interpolation in another interpolation is discouraged. Did you specify the parameter \"$degree\" on purpose?")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A very nice touch. 👍 |
||
end | ||
|
||
function box_extrapolation(itp::AbstractInterpolation, degree::Interpolations.Degree, args...) | ||
throw(ArgumentError("Boxing an interpolation in another interpolation is discouraged. Did you specify the parameter \"$degree\" on purpose?")) | ||
end | ||
|
||
function box_extrapolation(itp::AbstractExtrapolation, fill::FillType) | ||
throw(ArgumentError("Boxing an extrapolation in another extrapolation is discouraged. Did you specify the parameter \"$fill\" on purpose?")) | ||
end | ||
|
||
# This is type-piracy, but necessary if we want Interpolations to be | ||
# independent of OffsetArrays. | ||
function AxisAlgorithms.A_ldiv_B_md!(dest::OffsetArray, F, src::OffsetArray, dim::Integer, b::AbstractVector) | ||
indsdim = indices(parent(src), dim) | ||
indsF = indices(F)[2] | ||
if indsF == indsdim | ||
AxisAlgorithms.A_ldiv_B_md!(parent(dest), F, parent(src), dim, b) | ||
return dest | ||
end | ||
throw(DimensionMismatch("indices $(indices(parent(src))) do not match $(indices(F))")) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
""" | ||
InvWarpedView(img, tinv, [indices]) -> wv | ||
|
||
Create a view of `img` that lazily transforms any given index `I` | ||
passed to `wv[I]` to correspond to `img[inv(tinv)(I)]`. While | ||
technically this approach is known as backward mode warping, note | ||
that `InvWarpedView` is created by supplying the forward | ||
transformation | ||
|
||
The conceptual difference to [`WarpedView`](@ref) is that | ||
`InvWarpedView` is intended to be used when reasoning about the | ||
image is more convenient that reasoning about the indices. | ||
Furthermore, `InvWarpedView` allows simple nesting of | ||
transformations, in which case the transformations will be | ||
composed into a single one. | ||
|
||
The optional parameter `indices` can be used to specify the | ||
domain of the resulting `wv`. By default the indices are computed | ||
in such a way that `wv` contains all the original pixels in | ||
`img`. | ||
|
||
see [`invwarpedview`](@ref) for more information. | ||
""" | ||
immutable InvWarpedView{T,N,A,F,I,FI<:Transformation,E} <: AbstractArray{T,N} | ||
inner::WarpedView{T,N,A,F,I,E} | ||
inverse::FI | ||
end | ||
|
||
function InvWarpedView{T,N,TA,F,I,E}(inner::WarpedView{T,N,TA,F,I,E}) | ||
tinv = inv(inner.transform) | ||
InvWarpedView{T,N,TA,F,I,typeof(tinv),E}(inner, tinv) | ||
end | ||
|
||
function InvWarpedView(A::AbstractArray, tinv::Transformation, inds::Tuple = autorange(A, tinv)) | ||
InvWarpedView(WarpedView(A, inv(tinv), inds), tinv) | ||
end | ||
|
||
function InvWarpedView(inner::InvWarpedView, outer_tinv::Transformation) | ||
tinv = compose(outer_tinv, inner.inverse) | ||
InvWarpedView(parent(inner), tinv) | ||
end | ||
|
||
Base.parent(A::InvWarpedView) = parent(A.inner) | ||
@inline Base.indices(A::InvWarpedView) = indices(A.inner) | ||
|
||
@compat Compat.IndexStyle{T<:InvWarpedView}(::Type{T}) = IndexCartesian() | ||
@inline Base.getindex{T,N}(A::InvWarpedView{T,N}, I::Vararg{Int,N}) = A.inner[I...] | ||
|
||
Base.size(A::InvWarpedView) = size(A.inner) | ||
Base.size(A::InvWarpedView, d) = size(A.inner, d) | ||
|
||
function ShowItLikeYouBuildIt.showarg(io::IO, A::InvWarpedView) | ||
print(io, "InvWarpedView(") | ||
showarg(io, parent(A)) | ||
print(io, ", ") | ||
print(io, A.inverse) | ||
print(io, ')') | ||
end | ||
|
||
Base.summary(A::InvWarpedView) = summary_build(A) | ||
|
||
""" | ||
invwarpedview(img, tinv, [indices], [degree = Linear()], [fill = NaN]) -> wv | ||
|
||
Create a view of `img` that lazily transforms any given index `I` | ||
passed to `wv[I]` to correspond to `img[inv(tinv)(I)]`. While | ||
technically this approach is known as backward mode warping, note | ||
that `InvWarpedView` is created by supplying the forward | ||
transformation. The given transformation `tinv` must accept a | ||
`SVector` as input and support `inv(tinv)`. A useful package to | ||
create a wide variety of such transformations is | ||
[CoordinateTransformations.jl](https://github.com/FugroRoames/CoordinateTransformations.jl). | ||
|
||
When invoking `wv[I]`, values for `img` must be reconstructed at | ||
arbitrary locations `inv(tinv)(I)`. `InvWarpedView` serves as a | ||
wrapper around [`WarpedView`](@ref) which takes care of | ||
interpolation and extrapolation. The parameters `degree` and | ||
`fill` can be used to specify the b-spline degree and the | ||
extrapolation scheme respectively. | ||
|
||
The optional parameter `indices` can be used to specify the | ||
domain of the resulting `wv`. By default the indices are computed | ||
in such a way that `wv` contains all the original pixels in | ||
`img`. | ||
""" | ||
@inline invwarpedview(A::AbstractArray, tinv::Transformation, args...) = | ||
InvWarpedView(A, tinv, args...) | ||
|
||
function invwarpedview{T}( | ||
A::AbstractArray{T}, | ||
tinv::Transformation, | ||
degree::Union{Linear,Constant}, | ||
fill::FillType = _default_fill(T)) | ||
invwarpedview(box_extrapolation(A, degree, fill), tinv) | ||
end | ||
|
||
function invwarpedview{T}( | ||
A::AbstractArray{T}, | ||
tinv::Transformation, | ||
indices::Tuple, | ||
degree::Union{Linear,Constant}, | ||
fill::FillType = _default_fill(T)) | ||
invwarpedview(box_extrapolation(A, degree, fill), tinv, indices) | ||
end | ||
|
||
function invwarpedview( | ||
A::AbstractArray, | ||
tinv::Transformation, | ||
fill::FillType) | ||
invwarpedview(A, tinv, Linear(), fill) | ||
end | ||
|
||
function invwarpedview( | ||
A::AbstractArray, | ||
tinv::Transformation, | ||
indices::Tuple, | ||
fill::FillType) | ||
invwarpedview(A, tinv, indices, Linear(), fill) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does the
box_
signify?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just that the image is "boxed" or "decorated" by an extrapolation. It's supposed to signify that this will be a view.
Can you think of a better name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was tempted by
wrap_extrapolation
, but I think that could be confusing: people might think it's a typo ofwarp
! So let's stay withbox
. (EDIT: originally I had a typo in the word typo. Amusing!)