From f0d6da4afa16d710dc1467f24acc000b7edf63cf Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sun, 10 Oct 2021 13:37:23 -0500 Subject: [PATCH 1/4] =?UTF-8?q?Fix=20imrotate=20for=20Irrational=20=CE=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/warp.jl | 12 +++++++++--- test/warp.jl | 6 ++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/warp.jl b/src/warp.jl index 1049d9d..4c102d2 100644 --- a/src/warp.jl +++ b/src/warp.jl @@ -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{:π}) = @SMatrix [-1 0; 0 1] diff --git a/test/warp.jl b/test/warp.jl index 80cbb38..b01cfec 100644 --- a/test/warp.jl +++ b/test/warp.jl @@ -465,5 +465,11 @@ 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 + end end end From 594c76738b75d92606a7ae600d32fc06bebcda8c Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sun, 10 Oct 2021 13:50:45 -0500 Subject: [PATCH 2/4] Also test the generic code path --- Project.toml | 3 ++- test/warp.jl | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index e6392a0..3a3a9a9 100644 --- a/Project.toml +++ b/Project.toml @@ -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"] diff --git a/test/warp.jl b/test/warp.jl index b01cfec..3d6bc43 100644 --- a/test/warp.jl +++ b/test/warp.jl @@ -1,5 +1,6 @@ using CoordinateTransformations, Rotations, TestImages, ImageCore, StaticArrays, OffsetArrays, Interpolations, LinearAlgebra using EndpointRanges +using Tau using Test, ReferenceTests include("twoints.jl") @@ -470,6 +471,11 @@ NaN NaN NaN NaN NaN NaN NaN @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 end end end From 4c7b7c2e8f742afa5ffce8b0ef4b8ee5fa16dab2 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sun, 10 Oct 2021 13:58:28 -0500 Subject: [PATCH 3/4] add more tests from #79 --- test/warp.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/warp.jl b/test/warp.jl index 3d6bc43..8e31a53 100644 --- a/test/warp.jl +++ b/test/warp.jl @@ -476,6 +476,13 @@ NaN NaN NaN NaN NaN NaN NaN @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 From 0e3e44d62481f551b4c94123935246e4b717e049 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sun, 10 Oct 2021 14:37:05 -0500 Subject: [PATCH 4/4] Fix type & value --- src/warp.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/warp.jl b/src/warp.jl index 4c102d2..5e248ac 100644 --- a/src/warp.jl +++ b/src/warp.jl @@ -259,4 +259,4 @@ _mod2pi(θ::Irrational{:π}) = θ _mod2pi(θ::Irrational) = mod2pi(float(θ)) rotmtrx2(θ) = RotMatrix{2}(θ) -rotmtrx2(θ::Irrational{:π}) = @SMatrix [-1 0; 0 1] +rotmtrx2(θ::Irrational{:π}) = RotMatrix(@SMatrix [-1 0; 0 -1])