JuliaImages / ImageFiltering.jl

Julia implementations of multidimensional array convolution and nonlinear stencil operations
Other
99 stars 51 forks source link

Error When Using `SMatrix` for FIR Separable Filtration #252

Open RoyiAvital opened 1 year ago

RoyiAvital commented 1 year ago

This code works:

using Images;
using StaticArrays;

mA = rand(RGB{Float32}, 2048, 2048);

vW = [0.2f0 -0.5f0 0.3f0];
vW = centered(vW);

imfilter(mA, (vW', vW), "replicate", ImageFiltering.Algorithm.FIR());

Yet with this change:

using Images;
using StaticArrays;

mA = rand(RGB{Float32}, 2048, 2048);

vW = SMatrix{1, 3, Float32}([0.2f0 -0.5f0 0.3f0]);
vW = centered(vW);

imfilter(mA, (vW', vW), "replicate", ImageFiltering.Algorithm.FIR());

It will fail.

Environment information:

zygmuntszpak commented 1 year ago

I've started looking into this and they key difference between the SMatrix and the standard array happens on line 998 of border.jl

expand(ind::AbstractUnitRange, pad::AbstractUnitRange) = typeof(ind)(first(ind)+first(pad):last(ind)+last(pad))

With a standard array, we have

typeof(ind) == OffsetArrays.IdOffsetRange{Int64, Base.OneTo{Int64}} 

whereas with the static array we have

typeof(ind) ==  OffsetArrays.IdOffsetRange{Int64, SOneTo{3}}

We also have:

first(ind)+first(pad):last(ind)+last(pad)  == -1:1

and it turns out that

OffsetArrays.IdOffsetRange{Int64, Base.OneTo{Int64}}(-1:1)

is valid whereas

OffsetArrays.IdOffsetRange{Int64, SOneTo{3}}(-1:1)

results in DimensionMismatch: -1:1 is inconsistent with SOneTo{3}.

I'm not familiar with the internals of OffsetArrays so would have to study that to understand what OffsetArrays.IdOffsetRange is supposed to do. I think @johnnychen94 contributed to that package, so he might have some insight.

zygmuntszpak commented 1 year ago

I think I've found a solution. Will try to make a pull-request soon once I confirm it works correctly.