Evizero / Augmentor.jl

A fast image augmentation library in Julia for machine learning.
https://evizero.github.io/Augmentor.jl/
Other
138 stars 47 forks source link

Flip does not work with augmentbatch #55

Closed DrChainsaw closed 1 year ago

DrChainsaw commented 4 years ago
julia> augmentbatch!(zeros(4,4,3,2), ones(4,4,3,2), FlipX())
ERROR: MethodError: no method matching toaffinemap(::NoOp, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true})
Closest candidates are:
  toaffinemap(::Augmentor.Operation, ::Any, ::Any) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:48     
  toaffinemap(::NoOp, ::AbstractArray{T,2} where T) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operations\noop.jl:17
  toaffinemap(::Either, ::Any, ::Any) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operations\either.jl:171
Stacktrace:
 [1] prepareaffine(::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:34
 [2] applylazy_fallback(::FlipX, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::Nothing) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:108
 [3] _applylazy(::FlipX, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::Nothing) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:100
 [4] applylazy(::FlipX, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::Nothing) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:85
 [5] applylazy at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:60 [inlined]
 [6] macro expansion at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\codegen.jl:76 [inlined]
 [7] macro expansion at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:130 [inlined]
 [8] _augment_avoid_eager at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:130 [inlined]
 [9] _augment_avoid_eager at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:126 [inlined]
 [10] augment!(::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::Tuple{FlipX}) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:112
 [11] augment!(::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::FlipX) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:109
 [12] augmentbatch! at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augmentbatch.jl:105 [inlined]
 [13] augmentbatch! at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augmentbatch.jl:94 [inlined] (repeats 2 times)
 [14] augmentbatch!(::Array{Float64,4}, ::Array{Float64,4}, ::FlipX) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augmentbatch.jl:85
 [15] top-level scope at none:0

With an implementation for the ND identity affine map the same issue appears for Flip:

julia> using LinearAlgebra

julia> using StaticArrays

julia> Augmentor.toaffinemap(::NoOp, img::AbstractArray{T,N}) where {T,N} = Augmentor.AffineMap(I, @SVector(zeros(N)))

julia> augmentbatch!(zeros(4,4,3,2), ones(4,4,3,2), FlipX())
ERROR: MethodError: no method matching toaffinemap(::FlipX, ::ImageTransformations.InvWarpedView{Float64,3,Interpolations.Extrapolation{Float64,3,Interpolations.BSplineInterpolation{Float64,3,SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true},Interpolations.BSpline{Interpolations.Linear},Tuple{Base.OneTo{Int64},Base.OneTo{Int64},Base.OneTo{Int64}}},Interpolations.BSpline{Interpolations.Linear},Interpolations.Flat{Nothing}},CoordinateTransformations.AffineMap{UniformScaling{Float64},SArray{Tuple{3},Float64,1,3}},Tuple{UnitRange{Int64},UnitRange{Int64},UnitRange{Int64}},CoordinateTransformations.AffineMap{UniformScaling{Bool},SArray{Tuple{3},Float64,1,3}},Interpolations.Extrapolation{Float64,3,Interpolations.BSplineInterpolation{Float64,3,SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true},Interpolations.BSpline{Interpolations.Linear},Tuple{Base.OneTo{Int64},Base.OneTo{Int64},Base.OneTo{Int64}}},Interpolations.BSpline{Interpolations.Linear},Interpolations.Flat{Nothing}}})
Closest candidates are:
  toaffinemap(::Augmentor.Operation, ::Any, ::Any) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:48     
  toaffinemap(::NoOp, ::AbstractArray{T,N}) where {T, N} at none:1
  toaffinemap(::FlipX, ::AbstractArray{T,2} where T) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operations\flip.jl:59
  ...
Stacktrace:
 [1] toaffinemap at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:48 [inlined]
 [2] applyaffine(::FlipX, ::ImageTransformations.InvWarpedView{Float64,3,Interpolations.Extrapolation{Float64,3,Interpolations.BSplineInterpolation{Float64,3,SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true},Interpolations.BSpline{Interpolations.Linear},Tuple{Base.OneTo{Int64},Base.OneTo{Int64},Base.OneTo{Int64}}},Interpolations.BSpline{Interpolations.Linear},Interpolations.Flat{Nothing}},CoordinateTransformations.AffineMap{UniformScaling{Float64},SArray{Tuple{3},Float64,1,3}},Tuple{UnitRange{Int64},UnitRange{Int64},UnitRange{Int64}},CoordinateTransformations.AffineMap{UniformScaling{Bool},SArray{Tuple{3},Float64,1,3}},Interpolations.Extrapolation{Float64,3,Interpolations.BSplineInterpolation{Float64,3,SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true},Interpolations.BSpline{Interpolations.Linear},Tuple{Base.OneTo{Int64},Base.OneTo{Int64},Base.OneTo{Int64}}},Interpolations.BSpline{Interpolations.Linear},Interpolations.Flat{Nothing}}}, ::Nothing) at 
E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:77
 [3] applylazy_fallback(::FlipX, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::Nothing) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:108
 [4] _applylazy(::FlipX, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::Nothing) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:100
 [5] applylazy(::FlipX, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::Nothing) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:85 
 [6] applylazy at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:60 [inlined]
 [7] macro expansion at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\codegen.jl:76 [inlined]
 [8] macro expansion at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:130 [inlined]
 [9] _augment_avoid_eager at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:130 [inlined]
 [10] _augment_avoid_eager at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:126 [inlined]
 [11] augment!(::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::Tuple{FlipX}) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:112
 [12] augment!(::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::FlipX) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:109
 [13] augmentbatch! at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augmentbatch.jl:105 [inlined]
 [14] augmentbatch! at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augmentbatch.jl:94 [inlined] (repeats 2 times)     
 [15] augmentbatch!(::Array{Float64,4}, ::Array{Float64,4}, ::FlipX) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augmentbatch.jl:85
 [16] top-level scope at none:0

With an ND implementation for flip it works:

julia> Augmentor.toaffinemap(::FlipX, img::AbstractArray{T,N}) where {T,N} = Augmentor.recenter(SMatrix{N,N}(Matrix{typeof(0.)}(I, N,N) .* [1, -1, ones(N-2)...]), Augmentor.center(img))

julia> augmentbatch!(zeros(4,4,3,2), ones(4,4,3,2), FlipX())
4×4×3×2 Array{Float64,4}:
...

It still needs an ND implementation of applystepview to work inside an Either:

julia> augmentbatch!(zeros(4,4,3,2), ones(4,4,3,2), FlipX(0.5))
ERROR: MethodError: no method matching applystepview(::FlipX, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::Nothing)
Closest candidates are:
  applystepview(::NoOp, ::AbstractArray, ::Any) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operations\noop.jl:27  
  applystepview(::FlipX, ::AbstractArray{T,2} where T, ::Any) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operations\flip.jl:65
  applystepview(::Crop, ::AbstractArray, ::Any) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operations\crop.jl:80  
  ...
Stacktrace:
 [1] applystepview at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:60 [inlined]
 [2] applystepview(::Either{2,Tuple{FlipX,NoOp}}, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::Int64) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operations\either.jl:204
 [3] macro expansion at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operations\either.jl:146 [inlined]
 [4] applylazy at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operations\either.jl:146 [inlined]
 [5] applylazy at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\operation.jl:60 [inlined]
 [6] macro expansion at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\codegen.jl:76 [inlined]
 [7] macro expansion at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:130 [inlined]
 [8] _augment_avoid_eager at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:130 [inlined]
 [9] _augment_avoid_eager at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:126 [inlined]
 [10] augment!(::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true}, ::Tuple{Either{2,Tuple{FlipX,NoOp}}}) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:112
 [11] augment! at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augment.jl:109 [inlined]
 [12] augmentbatch!(::CPU1{Nothing}, ::MLDataPattern.ObsView{SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true},Array{Float64,4},LearnBase.ObsDim.Last}, ::MLDataPattern.ObsView{SubArray{Float64,3,Array{Float64,4},Tuple{Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Base.Slice{Base.OneTo{Int64}},Int64},true},Array{Float64,4},LearnBase.ObsDim.Last}, ::Either{2,Tuple{FlipX,NoOp}}) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augmentbatch.jl:105
 [13] augmentbatch! at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augmentbatch.jl:94 [inlined] (repeats 2 times)     
 [14] augmentbatch!(::Array{Float64,4}, ::Array{Float64,4}, ::Either{2,Tuple{FlipX,NoOp}}) at E:\Programs\julia\.julia\packages\Augmentor\kkcKe\src\augmentbatch.jl:85
 [15] top-level scope at none:0

This seems to work:

julia> Augmentor.applystepview(::FlipX, img::AbstractArray{T,N}, param) where {T,N} = Augmentor.indirect_view(img, (1:1:size(img,1), size(img,2):-1:1, (1:1:size(img,i) for i in 3:N)...))

julia> augmentbatch!(zeros(4,4,3,2), ones(4,4,3,2), FlipX(0.5))
4×4×3×2 Array{Float64,4}:
...
barucden commented 3 years ago

This is generally the same issue as in #56.

DrChainsaw commented 1 year ago

Yup, now that I understood the root cause (use colorants instead of raw numbers) this is clear to me. Thanks!