Skip to content

Commit 9264ea2

Browse files
authored
Move *finite statistics functions from Images (#13)
1 parent 9232149 commit 9264ea2

File tree

6 files changed

+120
-9
lines changed

6 files changed

+120
-9
lines changed

Project.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ImageBase"
22
uuid = "c817782e-172a-44cc-b673-b171935fbb9e"
3-
version = "0.1.2"
3+
version = "0.1.3"
44

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

2425
[targets]
25-
test = ["Aqua", "Documenter", "Test", "ImageIO", "ImageMagick", "OffsetArrays", "StackViews", "TestImages"]
26+
test = ["Aqua", "Documenter", "Test", "ImageIO", "ImageMagick", "OffsetArrays", "Statistics", "StackViews", "TestImages"]

src/ImageBase.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ export
88
# finite difference on one-dimension
99
# originally from Images.jl
1010
fdiff,
11-
fdiff!
11+
fdiff!,
12+
13+
# basic image statistics, from Images.jl
14+
minfinite,
15+
maxfinite,
16+
maxabsfinite,
17+
meanfinite
1218

1319

1420
using Reexport
@@ -19,6 +25,7 @@ using ImageCore.OffsetArrays
1925

2026
include("diff.jl")
2127
include("restrict.jl")
28+
include("statistics.jl")
2229
include("compat.jl")
2330
include("deprecated.jl")
2431

src/deprecated.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

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

5+
@deprecate meanfinite(A, region) meanfinite(A; dims=region)
6+
57
# END 0.1 deprecation

src/statistics.jl

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
"""
2+
Map12(condition, f1, f2)
3+
4+
Creates a function mapping `x -> condition(x) ? f1(x) : f2(x)`.
5+
"""
6+
struct Map12{C,F1,F2}
7+
condition::C
8+
f1::F1
9+
f2::F2
10+
end
11+
(m::Map12)(x) = m.condition(x) ? m.f1(x) : m.f2(x)
12+
13+
minc(x, y) = min(x, y)
14+
minc(x::Color, y::Color) = mapc(min, x, y)
15+
maxc(x, y) = max(x, y)
16+
maxc(x::Color, y::Color) = mapc(max, x, y)
17+
18+
"""
19+
minfinite(A; kwargs...)
20+
21+
Calculate the minimum value in `A`, ignoring any values that are not finite (Inf or NaN).
22+
23+
The supported `kwargs` are those of `minimum(f, A; kwargs...)`.
24+
"""
25+
minfinite(A; kwargs...) = mapreduce(Map12(isfinite, identity, typemax), minc, A; kwargs...)
26+
27+
"""
28+
maxfinite(A; kwargs...)
29+
30+
Calculate the maximum value in `A`, ignoring any values that are not finite (Inf or NaN).
31+
32+
The supported `kwargs` are those of `maximum(f, A; kwargs...)`.
33+
"""
34+
maxfinite(A; kwargs...) = mapreduce(Map12(isfinite, identity, typemin), maxc, A; kwargs...)
35+
36+
"""
37+
maxabsfinite(A; kwargs...)
38+
39+
Calculate the maximum absolute value in `A`, ignoring any values that are not finite (Inf or NaN).
40+
41+
The supported `kwargs` are those of `maximum(f, A; kwargs...)`.
42+
"""
43+
maxabsfinite(A; kwargs...) = mapreduce(Map12(isfinite, abs, typemin), maxc, A; kwargs...)
44+
45+
"""
46+
meanfinite(A; kwargs...)
47+
48+
Compute the mean value of `A`, ignoring any non-finite values.
49+
50+
The supported `kwargs` are those of `sum(f, A; kwargs...)`.
51+
"""
52+
function meanfinite end
53+
54+
if Base.VERSION >= v"1.1"
55+
function meanfinite(A; kwargs...)
56+
s = sum(Map12(isfinite, identity, zero), A; kwargs...)
57+
n = sum(Map12(isfinite, x->true, x->false), A; kwargs...) # TODO: replace with `Returns`
58+
return s./n
59+
end
60+
else
61+
function meanfinite(A; kwargs...)
62+
s = sum(Map12(isfinite, identity, zero).(A); kwargs...)
63+
n = sum(Map12(isfinite, x->true, x->false).(A); kwargs...)
64+
return s./n
65+
end
66+
end

test/runtests.jl

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ using OffsetArrays: IdentityUnitRange
77

88
@testset "Project meta quality checks" begin
99
# Not checking compat section for test-only dependencies
10-
ambiguity_exclude_list = [
11-
# https://github.com/JuliaDiff/ChainRulesCore.jl/pull/367#issuecomment-869071000
12-
Base.:(==),
13-
]
14-
Aqua.test_ambiguities([ImageCore, Base, Core], exclude=ambiguity_exclude_list)
10+
Aqua.test_ambiguities(ImageBase)
1511
Aqua.test_all(ImageBase;
1612
ambiguities=false,
1713
project_extras=true,
@@ -23,9 +19,10 @@ using OffsetArrays: IdentityUnitRange
2319
doctest(ImageBase,manual = false)
2420
end
2521
end
26-
22+
2723
include("diff.jl")
2824
include("restrict.jl")
25+
include("statistics.jl")
2926

3027
@info "deprecations are expected"
3128
include("deprecated.jl")

test/statistics.jl

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using ImageBase
2+
using Statistics
3+
using Test
4+
5+
@testset "Reductions" begin
6+
_abs(x::Colorant) = mapreducec(abs, +, 0, x)
7+
8+
A = rand(5,5,3)
9+
img = colorview(RGB, PermutedDimsArray(A, (3,1,2)))
10+
s12 = sum(img, dims=(1,2))
11+
@test eltype(s12) <: RGB
12+
A = [NaN, 1, 2, 3]
13+
@test meanfinite(A, 1) [2]
14+
A = [NaN 1 2 3;
15+
NaN 6 5 4]
16+
mf = meanfinite(A, 1)
17+
@test isnan(mf[1])
18+
@test mf[1,2:end] [3.5,3.5,3.5]
19+
@test meanfinite(A, 2) reshape([2, 5], 2, 1)
20+
@test meanfinite(A, (1,2)) [3.5]
21+
@test minfinite(A) == 1
22+
@test maxfinite(A) == 6
23+
@test maxabsfinite(A) == 6
24+
A = rand(10:20, 5, 5)
25+
@test minfinite(A) == minimum(A)
26+
@test maxfinite(A) == maximum(A)
27+
A = reinterpret(N0f8, rand(0x00:0xff, 5, 5))
28+
@test minfinite(A) == minimum(A)
29+
@test maxfinite(A) == maximum(A)
30+
A = rand(Float32,3,5,5)
31+
img = colorview(RGB, A)
32+
dc = meanfinite(img, 1)-reshape(reinterpretc(RGB{Float32}, mean(A, dims=2)), (1,5))
33+
@test maximum(map(_abs, dc)) < 1e-6
34+
dc = minfinite(img)-RGB{Float32}(minimum(A, dims=(2,3))...)
35+
@test _abs(dc) < 1e-6
36+
dc = maxfinite(img)-RGB{Float32}(maximum(A, dims=(2,3))...)
37+
@test _abs(dc) < 1e-6
38+
end

0 commit comments

Comments
 (0)