From 515f11b71e439cb6119c06ac6e3a24d8a23ec555 Mon Sep 17 00:00:00 2001 From: ginkul Date: Mon, 7 Jun 2021 00:07:43 +0300 Subject: [PATCH 1/7] add imresize with fixed_point --- src/resizing.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/resizing.jl b/src/resizing.jl index 83099fb..3f19ef6 100644 --- a/src/resizing.jl +++ b/src/resizing.jl @@ -120,6 +120,22 @@ function imresize(original::AbstractArray{T,N}, new_inds::Indices{N}; kwargs...) end end +function imresize(original::AbstractArray{T,N}, new_size::Dims{N}, fixed_point::CartesianIndex; kwargs...) where {T,N} + Tnew = imresize_type(first(original)) + checkbounds(Bool, original, fixed_point) || error("given index $fixed_point is out of range") + topleft = firstindex.(Ref(original), (1, 2)) + offset = fixed_point.I .- new_size .* (fixed_point.I .- topleft) .÷ size(original) .- 1 + resized = OffsetArray(similar(original, Tnew, new_size), offset) + imresize!(resized, original; kwargs...) + resized[fixed_point] = original[fixed_point] + resized +end + +function imresize(original::AbstractArray{T,N}, fixed_point::CartesianIndex; ratio, kwargs...) where {T,N} + all(ratio .> 0) || throw(ArgumentError("ratio $ratio should be positive")) + new_size = ceil.(Int, size(original) .* ratio) # use ceil to avoid 0 + imresize(original, new_size, fixed_point; kwargs...) +end # To choose the output type, rather than forcing everything to # Float64 by multiplying by 1.0, we exploit the fact that the scale # changes correspond to integer ratios. We mimic ratio arithmetic From 342c9fdb4126336ab4796fd427ddaee8ef5504af Mon Sep 17 00:00:00 2001 From: ginkul Date: Mon, 7 Jun 2021 23:50:50 +0300 Subject: [PATCH 2/7] add struct FixedPoint --- src/ImageTransformations.jl | 4 +++- src/fixedpoint.jl | 16 ++++++++++++++++ src/resizing.jl | 15 ++++++++------- 3 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 src/fixedpoint.jl diff --git a/src/ImageTransformations.jl b/src/ImageTransformations.jl index 5d621c5..2feea78 100644 --- a/src/ImageTransformations.jl +++ b/src/ImageTransformations.jl @@ -26,8 +26,10 @@ export warpedview, InvWarpedView, invwarpedview, - imrotate + imrotate, + FixedPoint +include("fixedpoint.jl") include("autorange.jl") include("interpolations.jl") include("warp.jl") diff --git a/src/fixedpoint.jl b/src/fixedpoint.jl new file mode 100644 index 0000000..b2d3a6a --- /dev/null +++ b/src/fixedpoint.jl @@ -0,0 +1,16 @@ +""" + FixedPoint(dims) -> fp + +Create a fixed point which can be used in `imresize` and `imrotate` +functions in order to keep the value in this point the same, i.e., + +```jldoctest +img[fp] == imgr[fp] +``` +""" +struct FixedPoint{N} + p::CartesianIndex{N} +end + +FixedPoint(dims::Dims{N}) where N = FixedPoint{N}(CartesianIndex(dims)) +FixedPoint(dims::Int64...) = FixedPoint(Tuple(dims)) diff --git a/src/resizing.jl b/src/resizing.jl index 3f19ef6..4ff8c7a 100644 --- a/src/resizing.jl +++ b/src/resizing.jl @@ -57,7 +57,7 @@ upsample/downsample the image `img` to a given size `sz` or axes `inds` using in The output size is `ceil(Int, size(img).*ratio)`. If `ratio` is larger than `1`, it is an upsample operation. Otherwise it is a downsample operation. `ratio` can also be a tuple, in which case `ratio[i]` specifies the resize ratio at dimension `i`. -- `method::InterpolationType`: +- `method::InterpolationType`: specify the interpolation method used for reconstruction. conveniently, `methold` can also be a `Degree` type, in which case a `BSpline` object will be created. For example, `method = Linear()` is equivalent to `method = BSpline(Linear())`. @@ -120,18 +120,19 @@ function imresize(original::AbstractArray{T,N}, new_inds::Indices{N}; kwargs...) end end -function imresize(original::AbstractArray{T,N}, new_size::Dims{N}, fixed_point::CartesianIndex; kwargs...) where {T,N} +function imresize(original::AbstractArray{T,N}, new_size::Dims{N}, fixed_point::FixedPoint{N}; kwargs...) where {T,N} Tnew = imresize_type(first(original)) - checkbounds(Bool, original, fixed_point) || error("given index $fixed_point is out of range") - topleft = firstindex.(Ref(original), (1, 2)) - offset = fixed_point.I .- new_size .* (fixed_point.I .- topleft) .÷ size(original) .- 1 + fp = fixed_point.p + checkbounds(Bool, original, fp) || error("given point $fp is out of range") + topleft = firstindex.(Ref(original), Tuple(1:N)) + offset = fp.I .- new_size .* (fp.I .- topleft) .÷ size(original) .- 1 resized = OffsetArray(similar(original, Tnew, new_size), offset) imresize!(resized, original; kwargs...) - resized[fixed_point] = original[fixed_point] + resized[fp] = original[fp] resized end -function imresize(original::AbstractArray{T,N}, fixed_point::CartesianIndex; ratio, kwargs...) where {T,N} +function imresize(original::AbstractArray{T,N}, fixed_point::FixedPoint{N}; ratio, kwargs...) where {T,N} all(ratio .> 0) || throw(ArgumentError("ratio $ratio should be positive")) new_size = ceil.(Int, size(original) .* ratio) # use ceil to avoid 0 imresize(original, new_size, fixed_point; kwargs...) From 8c60c639e135de0cac1ee21ca7ae2ee66a3fa2ce Mon Sep 17 00:00:00 2001 From: ginkul Date: Mon, 7 Jun 2021 23:54:46 +0300 Subject: [PATCH 3/7] add examples of imresize with fixed point --- src/resizing.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/resizing.jl b/src/resizing.jl index 4ff8c7a..44a842e 100644 --- a/src/resizing.jl +++ b/src/resizing.jl @@ -83,6 +83,10 @@ imresize(img, (1:256, )) # 256*768 imresize(img, ratio = 0.5) #256*384 imresize(img, ratio = (2, 1)) # 1024*768 +# pass `FixedPoint` +imresize(img, (256, 384), FixedPoint(10, 15)) # 256*384, img[10,15] == imgr[10,15] +imresize(img, FixedPoint(10, 15), ratio = 0.5) # 256*384, img[10,15] == imgr[10,15] + # use different interpolation method imresize(img, (256, 384), method=Linear()) # 256*384 bilinear interpolation imresize(img, (256, 384), method=Lanczos4OpenCV()) # 256*384 OpenCV-compatible Lanczos 4 interpolation From 1d3fee947cd288c4e6bd7e9461d18f389859fc66 Mon Sep 17 00:00:00 2001 From: ginkulv Date: Tue, 8 Jun 2021 16:46:43 +0300 Subject: [PATCH 4/7] rename FixedPoint to CenterPoint --- src/ImageTransformations.jl | 4 ++-- src/centerpoint.jl | 16 ++++++++++++++++ src/fixedpoint.jl | 16 ---------------- src/resizing.jl | 14 +++++++------- 4 files changed, 25 insertions(+), 25 deletions(-) create mode 100644 src/centerpoint.jl delete mode 100644 src/fixedpoint.jl diff --git a/src/ImageTransformations.jl b/src/ImageTransformations.jl index 2feea78..40de667 100644 --- a/src/ImageTransformations.jl +++ b/src/ImageTransformations.jl @@ -27,9 +27,9 @@ export InvWarpedView, invwarpedview, imrotate, - FixedPoint + CenterPoint -include("fixedpoint.jl") +include("centerpoint.jl") include("autorange.jl") include("interpolations.jl") include("warp.jl") diff --git a/src/centerpoint.jl b/src/centerpoint.jl new file mode 100644 index 0000000..f8d2c6a --- /dev/null +++ b/src/centerpoint.jl @@ -0,0 +1,16 @@ +""" + CenterPoint(dims) -> cp + +Create a fixed point which can be used in `imresize` and `imrotate` +functions in order to keep the value in this point the same, i.e., + +```jldoctest +img[cp] == imgr[cp] +``` +""" +struct CenterPoint{N} + p::CartesianIndex{N} +end + +CenterPoint(dims::Dims{N}) where N = CenterPoint{N}(CartesianIndex(dims)) +CenterPoint(dims::Int64...) = CenterPoint(Tuple(dims)) diff --git a/src/fixedpoint.jl b/src/fixedpoint.jl deleted file mode 100644 index b2d3a6a..0000000 --- a/src/fixedpoint.jl +++ /dev/null @@ -1,16 +0,0 @@ -""" - FixedPoint(dims) -> fp - -Create a fixed point which can be used in `imresize` and `imrotate` -functions in order to keep the value in this point the same, i.e., - -```jldoctest -img[fp] == imgr[fp] -``` -""" -struct FixedPoint{N} - p::CartesianIndex{N} -end - -FixedPoint(dims::Dims{N}) where N = FixedPoint{N}(CartesianIndex(dims)) -FixedPoint(dims::Int64...) = FixedPoint(Tuple(dims)) diff --git a/src/resizing.jl b/src/resizing.jl index 44a842e..d606550 100644 --- a/src/resizing.jl +++ b/src/resizing.jl @@ -124,22 +124,22 @@ function imresize(original::AbstractArray{T,N}, new_inds::Indices{N}; kwargs...) end end -function imresize(original::AbstractArray{T,N}, new_size::Dims{N}, fixed_point::FixedPoint{N}; kwargs...) where {T,N} +function imresize(original::AbstractArray{T,N}, new_size::Dims{N}, center_point::CenterPoint{N}; kwargs...) where {T,N} Tnew = imresize_type(first(original)) - fp = fixed_point.p - checkbounds(Bool, original, fp) || error("given point $fp is out of range") + cp = center_point.p + checkbounds(Bool, original, cp) || error("given point $cp is out of range") topleft = firstindex.(Ref(original), Tuple(1:N)) - offset = fp.I .- new_size .* (fp.I .- topleft) .÷ size(original) .- 1 + offset = cp.I .- new_size .* (cp.I .- topleft) .÷ size(original) .- 1 resized = OffsetArray(similar(original, Tnew, new_size), offset) imresize!(resized, original; kwargs...) - resized[fp] = original[fp] + resized[cp] = original[cp] resized end -function imresize(original::AbstractArray{T,N}, fixed_point::FixedPoint{N}; ratio, kwargs...) where {T,N} +function imresize(original::AbstractArray{T,N}, center_point::CenterPoint{N}; ratio, kwargs...) where {T,N} all(ratio .> 0) || throw(ArgumentError("ratio $ratio should be positive")) new_size = ceil.(Int, size(original) .* ratio) # use ceil to avoid 0 - imresize(original, new_size, fixed_point; kwargs...) + imresize(original, new_size, center_point; kwargs...) end # To choose the output type, rather than forcing everything to # Float64 by multiplying by 1.0, we exploit the fact that the scale From 81ffd494d173574a25fc66a758f86f7cd290f64d Mon Sep 17 00:00:00 2001 From: ginkul Date: Wed, 30 Jun 2021 12:47:21 +0300 Subject: [PATCH 5/7] refactor imresize with FixedPoint --- src/centerpoint.jl | 2 +- src/resizing.jl | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/centerpoint.jl b/src/centerpoint.jl index f8d2c6a..1fc3c49 100644 --- a/src/centerpoint.jl +++ b/src/centerpoint.jl @@ -4,7 +4,7 @@ Create a fixed point which can be used in `imresize` and `imrotate` functions in order to keep the value in this point the same, i.e., -```jldoctest +```julia img[cp] == imgr[cp] ``` """ diff --git a/src/resizing.jl b/src/resizing.jl index d606550..dad8bbb 100644 --- a/src/resizing.jl +++ b/src/resizing.jl @@ -127,13 +127,11 @@ end function imresize(original::AbstractArray{T,N}, new_size::Dims{N}, center_point::CenterPoint{N}; kwargs...) where {T,N} Tnew = imresize_type(first(original)) cp = center_point.p - checkbounds(Bool, original, cp) || error("given point $cp is out of range") + checkbounds(original, cp) topleft = firstindex.(Ref(original), Tuple(1:N)) - offset = cp.I .- new_size .* (cp.I .- topleft) .÷ size(original) .- 1 - resized = OffsetArray(similar(original, Tnew, new_size), offset) - imresize!(resized, original; kwargs...) - resized[cp] = original[cp] - resized + offset = @. cp.I - new_size * (cp.I - topleft) ÷ $size(original) - 1 + newimage = OffsetArray(similar(original, Tnew, new_size), offset) + imresize!(newimage, original; kwargs...) end function imresize(original::AbstractArray{T,N}, center_point::CenterPoint{N}; ratio, kwargs...) where {T,N} From cb837d783d9d2445a1ef2e9b151da9a7fca7093a Mon Sep 17 00:00:00 2001 From: ginkul Date: Fri, 2 Jul 2021 20:44:24 +0300 Subject: [PATCH 6/7] add some tests and fix the description for CenterPoint --- src/resizing.jl | 6 +++--- test/resizing.jl | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/resizing.jl b/src/resizing.jl index dad8bbb..e9876bd 100644 --- a/src/resizing.jl +++ b/src/resizing.jl @@ -83,9 +83,9 @@ imresize(img, (1:256, )) # 256*768 imresize(img, ratio = 0.5) #256*384 imresize(img, ratio = (2, 1)) # 1024*768 -# pass `FixedPoint` -imresize(img, (256, 384), FixedPoint(10, 15)) # 256*384, img[10,15] == imgr[10,15] -imresize(img, FixedPoint(10, 15), ratio = 0.5) # 256*384, img[10,15] == imgr[10,15] +# pass `CenterPoint` +imresize(img, (256, 384), CenterPoint(10, 15)) # 256*384, img[10,15] ≈ imgr[10,15] +imresize(img, CenterPoint(10, 15), ratio = 0.5) # 256*384, img[10,15] ≈ imgr[10,15] # use different interpolation method imresize(img, (256, 384), method=Linear()) # 256*384 bilinear interpolation diff --git a/test/resizing.jl b/test/resizing.jl index 7fb0e6e..8ce023d 100644 --- a/test/resizing.jl +++ b/test/resizing.jl @@ -47,17 +47,23 @@ end test_imresize_interface(img, (5,10), (5,)) test_imresize_interface(img, (5,10), 1:5) # FIXME: @inferred failed test_imresize_interface(img, (5,10), (1:5,)) # FIXME: @inferred failed + test_imresize_interface(img, (5,5), (5,5), CenterPoint(1, 1)) + test_imresize_interface(img, (20,20), CenterPoint(1, 1), ratio = 2) + test_imresize_interface(img, (20,10), CenterPoint(1, 1), ratio = (2, 1)) @test_throws MethodError imresize(img,5.0,5.0) @test_throws MethodError imresize(img,(5.0,5.0)) @test_throws MethodError imresize(img,(5, 5.0)) @test_throws MethodError imresize(img,[5,5]) @test_throws UndefKeywordError imresize(img) + @test_throws UndefKeywordError imresize(img, CenterPoint(1, 1)) @test_throws DimensionMismatch imresize(img,(5,5,5)) @test_throws ArgumentError imresize(img, ratio = -0.5) @test_throws ArgumentError imresize(img, ratio = (-0.5, 1)) + @test_throws ArgumentError imresize(img, CenterPoint(1, 1), ratio = -0.5) @test_throws DimensionMismatch imresize(img, ratio=(5,5,5)) @test_throws DimensionMismatch imresize(img, (5,5,1)) + @test_throws BoundsError imresize(img, (5,5), CenterPoint(100, 100)) end end From dd9d5c7f0ddeab47cbf64e0a63eb2dc0c2180f09 Mon Sep 17 00:00:00 2001 From: ginkul Date: Fri, 23 Jul 2021 21:41:06 +0300 Subject: [PATCH 7/7] add some tests --- test/resizing.jl | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/resizing.jl b/test/resizing.jl index 8ce023d..fa92a69 100644 --- a/test/resizing.jl +++ b/test/resizing.jl @@ -155,6 +155,32 @@ end out = imresize(img, (0:127, 0:127), method=Lanczos4OpenCV()) @test axes(out) == (0:127, 0:127) @test OffsetArrays.no_offset_view(out) == imresize(img, (128, 128), method=Lanczos4OpenCV()) + + @test imresize(img, (128,128), method=Linear()) == imresize(img, (128,128), CenterPoint(1,1), method=Linear()) + @test imresize(img, (128,128), method=BSpline(Linear())) == imresize(img, (128,128), CenterPoint(1,1), method=BSpline(Linear())) + @test imresize(img, (128,128), method=Lanczos4OpenCV()) == imresize(img, (128,128), CenterPoint(1,1), method=Lanczos4OpenCV()) + + out = imresize(OffsetArray(img, -1, -1), (128,128), CenterPoint(1,1), method=Linear()) + @test imresize(img, (128,128), method=Linear()) == OffsetArrays.no_offset_view(out) + + out = imresize(OffsetArray(img, -1, -1), (128,128), CenterPoint(1,1), method=BSpline(Linear())) + @test imresize(img, (128,128), method=BSpline(Linear())) == OffsetArrays.no_offset_view(out) + + out = imresize(OffsetArray(img, -1, -1), (128,128), CenterPoint(1,1), method=Lanczos4OpenCV()) + @test imresize(img, (128,128), method=Lanczos4OpenCV()) == OffsetArrays.no_offset_view(out) + + #check negative CenterPoint + out = imresize(OffsetArray(img, -2, -2), (128,128), CenterPoint(-1,-1), method=Linear()) + @test imresize(img, (128,128), method=Linear()) == OffsetArrays.no_offset_view(out) + + out = imresize(OffsetArray(img, -2, -2), (128,128), CenterPoint(-1,-1), method=BSpline(Linear())) + @test imresize(img, (128,128), method=BSpline(Linear())) == OffsetArrays.no_offset_view(out) + + out = imresize(OffsetArray(img, -2, -2), (128,128), CenterPoint(-1,-1), method=Lanczos4OpenCV()) + @test imresize(img, (128,128), method=Lanczos4OpenCV()) == OffsetArrays.no_offset_view(out) + + #check CenterPoint consistency + @test imresize(img, (128, 128), CenterPoint(5, 5), method=Constant())[5,5] == img[5,5] end end