I am trying to convert an old Python script to Julia. At one point, the script makes a call to scipy.ndimage.gaussian_filter
, for which I presume the Julia equivalent should be ImageFiltering.imfilter
with Kernel.gaussian
. However, I cannot get the latter to replicate the output of the former.
Naively:
julia> using ImageFiltering, PyCall
julia> a = reshape(1:25, (5,5)) .|> Float64
5×5 Array{Float64,2}:
1.0 6.0 11.0 16.0 21.0
2.0 7.0 12.0 17.0 22.0
3.0 8.0 13.0 18.0 23.0
4.0 9.0 14.0 19.0 24.0
5.0 10.0 15.0 20.0 25.0
julia> py_filt = pyimport("scipy.ndimage").gaussian_filter(a, (1,0))
5×5 Array{Float64,2}:
1.42704 6.42704 11.427 16.427 21.427
2.06782 7.06782 12.0678 17.0678 22.0678
3.0 8.0 13.0 18.0 23.0
3.93218 8.93218 13.9322 18.9322 23.9322
4.57296 9.57296 14.573 19.573 24.573
julia> jl_naive = imfilter(a, Kernel.gaussian((1,0)))
5×5 Array{Float64,2}:
1.35318 6.35318 11.3532 16.3532 21.3532
2.05449 7.05449 12.0545 17.0545 22.0545
3.0 8.0 13.0 18.0 23.0
3.94551 8.94551 13.9455 18.9455 23.9455
4.64682 9.64682 14.6468 19.6468 24.6468
In this example, the first element is different by ~5%! Looking a bit deeper into the documentation for both functions, I notice that the default padding mode for the scipy function is “reflect” whereas Julia’s is “replicate”, however, changing this still does not yield the same array:
julia> jl_reflect = imfilter(a, Kernel.gaussian((1,0)), "reflect")
5×5 Array{Float64,2}:
1.70636 6.70636 11.7064 16.7064 21.7064
2.10898 7.10898 12.109 17.109 22.109
3.0 8.0 13.0 18.0 23.0
3.89102 8.89102 13.891 18.891 23.891
4.29364 9.29364 14.2936 19.2936 24.2936
Also Julia’s ImageFiltering reflect(Kernel.gaussian((1,0)))
has no effect.
These differences seem way too big to be due to floating point errors, so what else am I doing wrong?