ImageTransformations.jl icon indicating copy to clipboard operation
ImageTransformations.jl copied to clipboard

`imresize`/`imrotate` fixed point

Open johnnychen94 opened this issue 4 years ago • 4 comments

I think it makes sense to introduce the concept of fixed point to better enhance the imresize function.

A fixedpoint p is where imgr[p] == img[p] holds.

Three new methods will be introduced as new API:

const FixedPointType = Union{Dims, CartesianIndex}

imresize(img, sz, p::FixedPointType)
imresize(img, inds, p::FixedPointType)
imresize(img, p::FixedPointType; ratio)

There are many use cases of this, I'll just list one thing that made me propose the idea:


With this, we can improve (change) the behavior to OffsetArray. Currently, when the input is an OffsetArray:

using OffsetArray

x = OffsetArray(rand(5, 5), -3, -3)

imresize(x, (-5:5, -5:5)) |> axes # (-5:5, -5:5)

imresize(x, (10, 10)) |> axes # (1:10, 1:10)
imresize(x; ratio=2) |> axes # (1:10, 1:10)

This loss the axes information of our OffsetArray, we could change the behavior of it to

imresize(img::OffsetArray, sz::Dims) = imresize(img, sz, topleft(img))
imresize(img::OffsetArray; ratio) = imresize(img, topleft(img); ratio)

Use top left point as the default value because it is consistent with the case that the fixed point for imresize(img::Array, sz) is also the topleft. (1-based indexing).

johnnychen94 avatar May 19 '21 14:05 johnnychen94

Hi! I'm currently investigating your code and looking forward to contribute to it. But I can't understand, should those functions with FixedPointType as an argument always return OffsetArray? To me it feels like yes, otherwise it would be either a matrix with many empty values in it or with truncated values because of negative indices, except when that point is [1, 1]. Could you clear it out for me, am I wrong?

ginkulv avatar Jun 01 '21 19:06 ginkulv

But I can't understand, should those functions with FixedPointType as an argument always return OffsetArray?

Yes, I think OffsetArray is the simplest model to reason about without loss of any information. People who are interested in 1-based array type can always combine the output OffsetArray with PaddedArray. For example, layer composition is a simple demo of such composition.

This is also why we have to set p::FixedPointType as a positional argument; if we set it as a keyword argument, which does not participate in method dispatch, there will be type instability between Array and OffsetArray.

johnnychen94 avatar Jun 01 '21 19:06 johnnychen94

Actually, I think the fixed point concept can be introduced to imrotate as well, in which case it's normally understood as the rotation center.

johnnychen94 avatar Jun 01 '21 19:06 johnnychen94

Yes, I think OffsetArray is the simplest model to reason about without loss of any information.

Alright, I got it. Should be easy enough.

Actually, I think the fixed point concept can be introduced to imrotate as well, in which case it's normally understood as the rotation center.

Yeah, it totally makes sense.

ginkulv avatar Jun 01 '21 20:06 ginkulv