Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 18 additions & 22 deletions src/projective/affine.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,30 @@ end


"""
ScaleRatio(minlengths) <: ProjectiveTransform
ScaleRatio(ratios) <: ProjectiveTransform

Scales the aspect ratio
"""
struct ScaleRatio{N} <: ProjectiveTransform
ratios::NTuple{N}
end

# This allows for roundtrip through ScaleFixed and avoids code duplication
fixed_sizes(scale::ScaleRatio, bounds::Bounds) = round.(Int, scale.ratios .* length.(bounds.rs))

function getprojection(scale::ScaleRatio, bounds; randstate = nothing)
return scaleprojection(scale.ratios)
function getprojection(scale::ScaleRatio{N}, bounds::Bounds{N}; randstate = nothing) where N
return getprojection(ScaleFixed{N}(fixed_sizes(scale, bounds)), bounds; randstate)
end

function projectionbounds(tfm::ScaleRatio{N}, P, bounds::Bounds{N}; randstate = nothing) where N
projectionbounds(ScaleFixed{N}(fixed_sizes(tfm, bounds)), P, bounds; randstate)
end

"""
ScaleKeepAspect(minlengths) <: ProjectiveTransform

Scales the shortest side of `item` to `minlengths`, keeping the
original aspect ratio.
Scales the sides of `item` to be as least as large as `minlengths`,
keeping the original aspect ratio.

## Examples

Expand All @@ -42,28 +48,15 @@ struct ScaleKeepAspect{N} <: ProjectiveTransform
minlengths::NTuple{N, Int}
end

# This allows for roundtrip through ScaleFixed and avoids code duplication
fixed_sizes(scale::ScaleKeepAspect, bounds::Bounds) = round.(Int, maximum(scale.minlengths ./ length.(bounds.rs)) .* length.(bounds.rs))

function getprojection(scale::ScaleKeepAspect{N}, bounds::Bounds{N}; randstate = nothing) where N
# If no scaling needs to be done, return a noop transform
scale.minlengths == length.(bounds.rs) && return IdentityTransformation()

# Offset `minlengths` by 1 to avoid black border on one side
ratio = maximum((scale.minlengths .+ 1) ./ length.(bounds.rs))
upperleft = SVector{N, Float32}(minimum.(bounds.rs)) .- 0.5
P = scaleprojection(Tuple(ratio for _ in 1:N))
if any(upperleft .!= 0)
P = P ∘ Translation((Float32.(P(upperleft)) .+ 0.5f0))
end
return P
getprojection(ScaleFixed{N}(fixed_sizes(scale, bounds)), bounds; randstate)
end

function projectionbounds(tfm::ScaleKeepAspect{N}, P, bounds::Bounds{N}; randstate = nothing) where N
origsz = length.(bounds.rs)
ratio = maximum((tfm.minlengths) ./ origsz)
sz = round.(Int, ratio .* origsz)
bounds_ = transformbounds(bounds, P)
bs_ = offsetcropbounds(sz, bounds_, ntuple(_ -> 0.5, N))
return bs_
projectionbounds(ScaleFixed{N}(fixed_sizes(tfm, bounds)), P, bounds; randstate)
end

"""
Expand All @@ -80,6 +73,9 @@ end


function getprojection(scale::ScaleFixed, bounds::Bounds{N}; randstate = nothing) where N
# If no scaling needs to be done, return a noop transform
(scale.sizes == length.(bounds.rs)) && return IdentityTransformation()

ratios = (scale.sizes .+ 1) ./ length.(bounds.rs)
upperleft = SVector{N, Float32}(minimum.(bounds.rs)) .- 1
P = scaleprojection(ratios)
Expand Down
12 changes: 9 additions & 3 deletions test/projective/affine.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ include("../imports.jl")
@test_nowarn apply(tfm, keypoints)
timage = apply(tfm, image)
tkeypoints = apply(tfm, keypoints)
@test !any(isnan.(timage |> itemdata))
@test length.(getbounds(timage).rs) == (25, 25)
@test getbounds(timage) == getbounds(tkeypoints)
testprojective(tfm)
Expand All @@ -87,7 +88,8 @@ include("../imports.jl")
@test_nowarn apply(tfm, keypoints)
timage = apply(tfm, image)
tkeypoints = apply(tfm, keypoints)
@test getbounds(timage).rs == (0:25, 0:25)
@test !any(isnan.(timage |> itemdata))
@test getbounds(timage).rs == (2:26, 2:26)
@test getbounds(timage) == getbounds(tkeypoints)
testprojective(tfm)
end
Expand All @@ -96,10 +98,14 @@ include("../imports.jl")
tfm = ScaleKeepAspect((32, 32))

img = rand(RGB{N0f8}, 64, 96)
@test apply(tfm, Image(img)) |> itemdata |> size == (32, 48)
timg = apply(tfm, Image(img)) |> itemdata
@test timg |> size == (32, 48)
@test !any(isnan.(timg))

img = rand(RGB{N0f8}, 196, 196)
@test apply(tfm, Image(img)) |> itemdata |> size == (32, 32)
timg = apply(tfm, Image(img)) |> itemdata
@test timg |> size == (32, 32)
@test !any(isnan.(timg))
end
end

Expand Down
Loading