Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions src/lanczos/lanczos_opencv.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ export Lanczos4OpenCV
Alternative implementation of Lanczos resampling using algorithm `lanczos4` function of OpenCV:
https://github.com/opencv/opencv/blob/de15636724967faf62c2d1bce26f4335e4b359e5/modules/imgproc/src/resize.cpp#L917-L946
"""
struct Lanczos4OpenCV <: AbstractLanczos end
struct Lanczos4OpenCV{T} <: AbstractLanczos end
Lanczos4OpenCV() = Lanczos4OpenCV{Float64}()

degree(::Lanczos4OpenCV) = 4

value_weights(::Lanczos4OpenCV, δx) = _lanczos4_opencv(δx)
value_weights(::Lanczos4OpenCV{T}, δx) where {T} =
_lanczos4_opencv(float(T), float(T).(l4_2d_cs), δx)

# s45 = sqrt(2)/2
const s45 = 0.70710678118654752440084436210485
Expand All @@ -65,20 +67,18 @@ const s45 = 0.70710678118654752440084436210485
const l4_2d_cs = SA[1 0; -s45 -s45; 0 1; s45 -s45; -1 0; s45 s45; 0 -1; -s45 s45]


function _lanczos4_opencv(δx)
p_4 = π / 4
y0 = -(δx + 3) * p_4
function _lanczos4_opencv(::Type{F}, l4_2d_cs, δx) where {F}
p_4 = π * F(0.25)
y0 = -(δx + F(3)) * p_4
s0, c0 = sincos(y0)
cs = ntuple(8) do i
y = (δx + 4 - i) * p_4
# Improve precision of Lanczos OpenCV4 #451, avoid NaN
if iszero(y)
y = eps(oneunit(y))/8
y = δx + 4 - i
if abs(y) >= F(1e-6)
y *= p_4
(F(l4_2d_cs[i, 1]) * s0 + F(l4_2d_cs[i, 2]) * c0) / y^2
else
F(1e30)
end
# Numerator is the sin subtraction identity
# It is equivalent to the following
# f(δx,i) = sin( π/4*( 5*(i-1)-δx-3 ) )
(l4_2d_cs[i, 1] * s0 + l4_2d_cs[i, 2] * c0) / y^2
end
sum_cs = sum(cs)
normed_cs = ntuple(i -> cs[i] / sum_cs, Val(8))
Expand Down
Loading