Skip to content

Commit

Permalink
Add box and laplacian2d (#226)
Browse files Browse the repository at this point in the history
These come from Images.jl and are part of moving most/all code
out to make it a meta-package.
  • Loading branch information
timholy authored Sep 5, 2021
1 parent 9ce17bd commit 6b51789
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/kernel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ function product2d(kf)
k1[1].*k1[2], k2[1].*k2[2]
end

"""
kern = box((m, n, ...))
Return a box kernel computing a moving average. `m, n, ...` specify the size of the kernel, which is centered around zero.
"""
box(sz::Dims) = broadcast(*, KernelFactors.box(sz)...)
# We don't support box(m::Int...) mostly because of `gaussian(σ::Real) = gaussian((σ, σ))` defaulting to
# isotropic 2d rather than a 1d Gaussian.

"""
```julia
diff1, diff2 = sobel()
Expand Down Expand Up @@ -380,6 +389,40 @@ function Base.convert(::Type{AbstractArray}, L::Laplacian{N}) where N
end
_reshape(L::Laplacian{N}, ::Val{N}) where {N} = L

"""
laplacian2d(alpha::Number)
Construct a weighted discrete Laplacian approximation in 2d. `alpha` controls the weighting of the faces
relative to the corners.
# Examples
```jldoctest
julia> Kernel.laplacian2d(0) # the standard Laplacian
3×3 OffsetArray(::Matrix{Float64}, -1:1, -1:1) with eltype Float64 with indices -1:1×-1:1:
0.0 1.0 0.0
1.0 -4.0 1.0
0.0 1.0 0.0
julia> Kernel.laplacian2d(1) # a corner-focused Laplacian
3×3 OffsetArray(::Matrix{Float64}, -1:1, -1:1) with eltype Float64 with indices -1:1×-1:1:
0.5 0.0 0.5
0.0 -2.0 0.0
0.5 0.0 0.5
julia> Kernel.laplacian2d(0.5) # equal weight for face-pixels and corner-pixels.
3×3 OffsetArray(::Matrix{Float64}, -1:1, -1:1) with eltype Float64 with indices -1:1×-1:1:
0.333333 0.333333 0.333333
0.333333 -2.66667 0.333333
0.333333 0.333333 0.333333
```
"""
function laplacian2d(alpha::Number=0)
lc = alpha/(1 + alpha)
lb = (1 - alpha)/(1 + alpha)
lm = -4/(1 + alpha)
return centered([lc lb lc; lb lm lb; lc lb lc])
end

"""
gabor(size_x,size_y,σ,θ,λ,γ,ψ) -> (k_real,k_complex)
Expand Down
13 changes: 13 additions & 0 deletions src/kernelfactors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
each stored in terms of their factors. The following kernels are
supported:
- `box`
- `sobel`
- `prewitt`
- `ando3`, `ando4`, and `ando5` (the latter in 2d only)
Expand Down Expand Up @@ -148,6 +149,18 @@ end

#### FIR filters

"""
kern1, kern2 = box(m, n)
kerns = box((m, n, ...))
Return a tuple of "flat" kernels, where, for example, `kern1[i] == 1/m` and has length `m`.
"""
function box(sz::Dims)
all(isodd, sz) || throw(ArgumentError("kernel dimensions must be odd, got $sz"))
return kernelfactors(ntuple(d -> centered([1/sz[d] for i=1:sz[d]]), length(sz)))
end
box(sz::Int...) = box(sz)

## gradients

"""
Expand Down
13 changes: 13 additions & 0 deletions test/specialty.jl
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,19 @@ using ImageFiltering: IdentityUnitRange
z z z z edgecoef*c]
end
end
@test Kernel.laplacian2d(0.5) centered([ 1/3 1/3 1/3;
1/3 -8/3 1/3;
1/3 1/3 1/3])
end

@testset "box" begin
@test KernelFactors.box(3) == (centered([1/3, 1/3, 1/3]),)
@test KernelFactors.box(3, 5) == (centered(reshape([1/3, 1/3, 1/3], 3, 1)), centered([1/5, 1/5, 1/5, 1/5, 1/5]'))
@test KernelFactors.box((3,5,7)) == KernelFactors.box(3, 5, 7)
@test Kernel.box((3,)) == centered([1/3, 1/3, 1/3])
@test Kernel.box((3, 5)) == centered([1/3, 1/3, 1/3] .* [1/5, 1/5, 1/5, 1/5, 1/5]')
@test_throws ArgumentError KernelFactors.box((3, 4, 5))
@test_throws ArgumentError Kernel.box((3, 4, 5))
end

@testset "gaussian" begin
Expand Down

2 comments on commit 6b51789

@timholy
Copy link
Member Author

@timholy timholy commented on 6b51789 Sep 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/44258

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.7.0 -m "<description of version>" 6b517897b1423139304e6a509fd030039fd89d8e
git push origin v0.7.0

Please sign in to comment.