Skip to content

Commit 3abde17

Browse files
committed
Fix off-by-one error for Scale transformations that would lead to black border
1 parent f4988d2 commit 3abde17

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

src/projective/affine.jl

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,23 @@ end
4040

4141

4242
function getprojection(scale::ScaleKeepAspect{N}, bounds; randstate = nothing) where N
43-
ratio = maximum(scale.minlengths ./ length.(bounds.rs))
43+
# Offset `minlengths` by 1 to avoid black border on one side
44+
ratio = maximum((scale.minlengths .+ 1) ./ length.(bounds.rs))
4445
upperleft = SVector{N, Float32}(minimum.(bounds.rs)) .- 1
4546
P = scaleprojection(Tuple(ratio for _ in 1:N))
4647
if upperleft != SVector(0, 0)
47-
P = P Translation(-upperleft)
48+
P = P Translation(-upperleft)
4849
end
4950
return P
5051
end
5152

5253
function projectionbounds(tfm::ScaleKeepAspect{N}, P, bounds::Bounds{N}; randstate = nothing) where N
5354
origsz = length.(bounds.rs)
54-
ratio = maximum(tfm.minlengths ./ origsz)
55-
sz = round.(Int, ratio .* origsz)
55+
ratio = maximum((tfm.minlengths .+ 1) ./ origsz)
56+
sz = floor.(Int, ratio .* origsz)
5657
bounds_ = transformbounds(bounds, P)
57-
return offsetcropbounds(sz, bounds_, ntuple(_ -> 1., N))
58+
bs_ = offsetcropbounds(sz, bounds_, ntuple(_ -> 1., N))
59+
return bs_
5860
end
5961

6062
"""
@@ -71,7 +73,7 @@ end
7173

7274

7375
function getprojection(scale::ScaleFixed, bounds; randstate = nothing)
74-
ratios = scale.sizes ./ length.(bounds.rs)
76+
ratios = (scale.sizes .+ 1) ./ length.(bounds.rs)
7577
upperleft = SVector{2, Float32}(minimum.(bounds.rs)) .- 1
7678
P = scaleprojection(ratios)
7779
if upperleft != SVector(0, 0)
@@ -209,11 +211,12 @@ at one.
209211
struct PinOrigin <: ProjectiveTransform end
210212

211213
function getprojection(::PinOrigin, bounds; randstate = nothing)
212-
# TODO: translate by actual minimum x and y coordinates
213-
return Translation((-SVector{2, Float32}(minimum.(bounds.rs))) .+ 1)
214+
p = (-SVector{2, Float32}(minimum.(bounds.rs))) .+ 1
215+
P = Translation(p)
216+
return P
214217
end
215218

216-
function apply(::PinOrigin, item::Union{Image, MaskMulti, MaskBinary}; randstate = nothing)
219+
function apply(::PinOrigin, item::Union{<:Image, <:MaskMulti, <:MaskBinary}; randstate = nothing)
217220
item = @set item.data = parent(itemdata(item))
218221
item = @set item.bounds = Bounds(size(itemdata(item)))
219222
return item
@@ -229,6 +232,8 @@ end
229232
# This overwrites the default composition.
230233

231234
compose(cropped::CroppedProjectiveTransform, pin::PinOrigin) = Sequence(cropped, pin)
235+
compose(cropped::ComposedProjectiveTransform, pin::PinOrigin) = Sequence(cropped, pin)
236+
compose(cropped::ProjectiveTransform, pin::PinOrigin) = Sequence(cropped, pin)
232237

233238
# ## Resize crops
234239

0 commit comments

Comments
 (0)