Skip to content
Merged
Show file tree
Hide file tree
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
5 changes: 3 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "ImageBase"
uuid = "c817782e-172a-44cc-b673-b171935fbb9e"
version = "0.1.2"
version = "0.1.3"

[deps]
ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534"
Expand All @@ -18,8 +18,9 @@ ImageIO = "82e4d734-157c-48bb-816b-45c225c6df19"
ImageMagick = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
StackViews = "cae243ae-269e-4f55-b966-ac2d0dc13c15"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
TestImages = "5e47fb64-e119-507b-a336-dd2b206d9990"

[targets]
test = ["Aqua", "Documenter", "Test", "ImageIO", "ImageMagick", "OffsetArrays", "StackViews", "TestImages"]
test = ["Aqua", "Documenter", "Test", "ImageIO", "ImageMagick", "OffsetArrays", "Statistics", "StackViews", "TestImages"]
9 changes: 8 additions & 1 deletion src/ImageBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ export
# finite difference on one-dimension
# originally from Images.jl
fdiff,
fdiff!
fdiff!,

# basic image statistics, from Images.jl
minfinite,
maxfinite,
maxabsfinite,
meanfinite


using Reexport
Expand All @@ -19,6 +25,7 @@ using ImageCore.OffsetArrays

include("diff.jl")
include("restrict.jl")
include("statistics.jl")
include("compat.jl")
include("deprecated.jl")

Expand Down
2 changes: 2 additions & 0 deletions src/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

@deprecate restrict(A::AbstractArray, region::Vector{Int}) restrict(A, (region...,))

@deprecate meanfinite(A, region) meanfinite(A; dims=region)

# END 0.1 deprecation
66 changes: 66 additions & 0 deletions src/statistics.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""
Map12(condition, f1, f2)

Creates a function mapping `x -> condition(x) ? f1(x) : f2(x)`.
"""
struct Map12{C,F1,F2}
condition::C
f1::F1
f2::F2
end
(m::Map12)(x) = m.condition(x) ? m.f1(x) : m.f2(x)

minc(x, y) = min(x, y)
minc(x::Color, y::Color) = mapc(min, x, y)
maxc(x, y) = max(x, y)
maxc(x::Color, y::Color) = mapc(max, x, y)

"""
minfinite(A; kwargs...)

Calculate the minimum value in `A`, ignoring any values that are not finite (Inf or NaN).

The supported `kwargs` are those of `minimum(f, A; kwargs...)`.
"""
minfinite(A; kwargs...) = mapreduce(Map12(isfinite, identity, typemax), minc, A; kwargs...)

"""
maxfinite(A; kwargs...)

Calculate the maximum value in `A`, ignoring any values that are not finite (Inf or NaN).

The supported `kwargs` are those of `maximum(f, A; kwargs...)`.
"""
maxfinite(A; kwargs...) = mapreduce(Map12(isfinite, identity, typemin), maxc, A; kwargs...)

"""
maxabsfinite(A; kwargs...)

Calculate the maximum absolute value in `A`, ignoring any values that are not finite (Inf or NaN).

The supported `kwargs` are those of `maximum(f, A; kwargs...)`.
"""
maxabsfinite(A; kwargs...) = mapreduce(Map12(isfinite, abs, typemin), maxc, A; kwargs...)

"""
meanfinite(A; kwargs...)

Compute the mean value of `A`, ignoring any non-finite values.

The supported `kwargs` are those of `sum(f, A; kwargs...)`.
"""
function meanfinite end

if Base.VERSION >= v"1.1"
function meanfinite(A; kwargs...)
s = sum(Map12(isfinite, identity, zero), A; kwargs...)
n = sum(Map12(isfinite, x->true, x->false), A; kwargs...) # TODO: replace with `Returns`
return s./n
end
else
function meanfinite(A; kwargs...)
s = sum(Map12(isfinite, identity, zero).(A); kwargs...)
n = sum(Map12(isfinite, x->true, x->false).(A); kwargs...)
return s./n
end
end
9 changes: 3 additions & 6 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ using OffsetArrays: IdentityUnitRange

@testset "Project meta quality checks" begin
# Not checking compat section for test-only dependencies
ambiguity_exclude_list = [
# https://github.com/JuliaDiff/ChainRulesCore.jl/pull/367#issuecomment-869071000
Base.:(==),
]
Aqua.test_ambiguities([ImageCore, Base, Core], exclude=ambiguity_exclude_list)
Aqua.test_ambiguities(ImageBase)
Aqua.test_all(ImageBase;
ambiguities=false,
project_extras=true,
Expand All @@ -23,9 +19,10 @@ using OffsetArrays: IdentityUnitRange
doctest(ImageBase,manual = false)
end
end

include("diff.jl")
include("restrict.jl")
include("statistics.jl")

@info "deprecations are expected"
include("deprecated.jl")
Expand Down
38 changes: 38 additions & 0 deletions test/statistics.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using ImageBase
using Statistics
using Test

@testset "Reductions" begin
_abs(x::Colorant) = mapreducec(abs, +, 0, x)

A = rand(5,5,3)
img = colorview(RGB, PermutedDimsArray(A, (3,1,2)))
s12 = sum(img, dims=(1,2))
@test eltype(s12) <: RGB
A = [NaN, 1, 2, 3]
@test meanfinite(A, 1) ≈ [2]
A = [NaN 1 2 3;
NaN 6 5 4]
mf = meanfinite(A, 1)
@test isnan(mf[1])
@test mf[1,2:end] ≈ [3.5,3.5,3.5]
@test meanfinite(A, 2) ≈ reshape([2, 5], 2, 1)
@test meanfinite(A, (1,2)) ≈ [3.5]
@test minfinite(A) == 1
@test maxfinite(A) == 6
@test maxabsfinite(A) == 6
A = rand(10:20, 5, 5)
@test minfinite(A) == minimum(A)
@test maxfinite(A) == maximum(A)
A = reinterpret(N0f8, rand(0x00:0xff, 5, 5))
@test minfinite(A) == minimum(A)
@test maxfinite(A) == maximum(A)
A = rand(Float32,3,5,5)
img = colorview(RGB, A)
dc = meanfinite(img, 1)-reshape(reinterpretc(RGB{Float32}, mean(A, dims=2)), (1,5))
@test maximum(map(_abs, dc)) < 1e-6
dc = minfinite(img)-RGB{Float32}(minimum(A, dims=(2,3))...)
@test _abs(dc) < 1e-6
dc = maxfinite(img)-RGB{Float32}(maximum(A, dims=(2,3))...)
@test _abs(dc) < 1e-6
end