Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ ImageIO = "82e4d734-157c-48bb-816b-45c225c6df19"
ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
ReferenceTests = "324d217c-45ce-50fc-942e-d289b448e8cf"
Tau = "c544e3c2-d3e5-5802-ac44-44683f340e4a"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
TestImages = "5e47fb64-e119-507b-a336-dd2b206d9990"

[targets]
test = ["EndpointRanges", "ImageIO", "ImageMagick", "LinearAlgebra", "ReferenceTests", "Test", "TestImages"]
test = ["EndpointRanges", "ImageIO", "ImageMagick", "LinearAlgebra", "ReferenceTests", "Tau", "Test", "TestImages"]
12 changes: 9 additions & 3 deletions src/warp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,19 @@ mosaicview([imgr for _ in 1:9]; nrow=3)
"""
function imrotate(img::AbstractArray{T}, θ::Real, inds::Union{Tuple, Nothing} = nothing; kwargs...) where T
# TODO: expose rotation center as a keyword
Δ = eps(θ)
θ = mod2pi(θ)
Δ = eps(float(θ))
θ = _mod2pi(θ)
if abs(θ) <= Δ || abs(θ - 2π) <= Δ
θ = zero(θ)
end
tform = recenter(RotMatrix{2}(θ), center(img))
tform = recenter(rotmtrx2(θ), center(img))
# Use the `nothing` trick here because moving the `autorange` as default value is not type-stable
inds = isnothing(inds) ? autorange(img, inv(tform)) : inds
warp(img, tform, inds; kwargs...)
end
_mod2pi(θ) = mod2pi(θ)
_mod2pi(θ::Irrational{:π}) = θ
_mod2pi(θ::Irrational) = mod2pi(float(θ))

rotmtrx2(θ) = RotMatrix{2}(θ)
rotmtrx2(θ::Irrational{:π}) = RotMatrix(@SMatrix [-1 0; 0 -1])
19 changes: 19 additions & 0 deletions test/warp.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using CoordinateTransformations, Rotations, TestImages, ImageCore, StaticArrays, OffsetArrays, Interpolations, LinearAlgebra
using EndpointRanges
using Tau
using Test, ReferenceTests

include("twoints.jl")
Expand Down Expand Up @@ -465,5 +466,23 @@ NaN NaN NaN NaN NaN NaN NaN
@test !any(isnan, imrotate(img, π/3, axes(img); fillvalue=0.0))
@test !any(isnan, imrotate(img, π/3, axes(img), fillvalue=0.0))
end

@testset "Examples from #79" begin
@test axes(imrotate(img_camera, pi/2)) == axes(img_camera)
@test imrotate(imrotate(imrotate(imrotate(img_camera, pi/2), pi/2), pi/2), pi/2) ≈ img_camera
@test imrotate(imrotate(img_camera, pi), pi) == img_camera
# Also check a "generic" irrational (one that happens to be quite special)
## First, check that this hits the generic code path (if we change that, pick a different irrational)
@test ImageTransformations._mod2pi(τ) isa Float64
## Now check that it gives the expected result
@test imrotate(img_camera, τ) ≈ img_camera

# check special rotation degrees
img = rand(Gray{N0f8}, 100, 50)
@test size(imrotate(img, pi/2)) == (50, 100)
@test size(imrotate(img, pi)) == (100, 50)
@test size(imrotate(img, 3pi/2)) == (50, 100)
@test size(imrotate(img, 2pi)) == (100, 50)
end
end
end