Skip to content

Commit 42795dd

Browse files
committed
Introduces AbstractIntensityAdjustmentAlgorithm
1 parent 37000d7 commit 42795dd

File tree

4 files changed

+192
-9
lines changed

4 files changed

+192
-9
lines changed

src/HistogramAdjustmentAPI/HistogramAdjustmentAPI.jl renamed to src/ContrastAdjustmentAPI/ContrastAdjustmentAPI.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This is a temporary module to validate `AbstractImageFilter` idea
22
# proposed in https://github.com/JuliaImages/ImagesAPI.jl/pull/3
3-
module HistogramAdjustmentAPI
3+
module ContrastAdjustmentAPI
44

55
using ImageCore # ColorTypes is sufficient
66

@@ -22,8 +22,9 @@ Filters are image algorithms whose input and output are both images
2222
abstract type AbstractImageFilter <: AbstractImageAlgorithm end
2323

2424
include("histogram_adjustment.jl")
25+
include("intensity_adjustment.jl")
2526

2627
# we do not export any symbols since we don't require
2728
# package developers to implemente all the APIs
2829

29-
end # module HistogramAdjustmentAPI
30+
end # module ContrastAdjustmentAPI

src/HistogramAdjustmentAPI/histogram_adjustment.jl renamed to src/ContrastAdjustmentAPI/histogram_adjustment.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# usage example for package developer:
22
#
3-
# import HistogramAdjustmentAPI: AbstractHistogramAdjustmentAlgorithm,
3+
# import ContrastAdjustmentAPI: AbstractHistogramAdjustmentAlgorithm,
44
# adjust_histogram, adjust_histogram!
55

66
"""
77
AbstractHistogramAdjustmentAlgorithm <: AbstractImageFilter
88
9-
The root type for `ImageContrastAdjustment` package.
9+
A root type for `ImageContrastAdjustment` package that relates to algorithms
10+
that manipulate contrast by operating on intensity histograms.
1011
1112
Any concrete histogram adjustment algorithm shall subtype it to support
1213
[`adjust_histogram`](@ref) and [`adjust_histogram!`](@ref) APIs.
@@ -18,7 +19,7 @@ following pattern:
1819
1920
```julia
2021
# first generate an algorithm instance
21-
f = LinearStretching()
22+
f = Equalization()
2223
2324
# then pass the algorithm to `adjust_histogram`
2425
img_adjusted = adjust_histogram(img, f)
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# usage example for package developer:
2+
#
3+
# import ContrastAdjustmentAPI: AbstractIntensityAdjustmentAlgorithm,
4+
# adjust_intensity, adjust_intensity!
5+
6+
"""
7+
AbstractIntensityAdjustmentAlgorithm <: AbstractImageFilter
8+
9+
A root type for `ImageContrastAdjustment` package that relates to algorithms
10+
that manipulate contrast without operating on intensity histograms.
11+
12+
Any concrete intensity adjustment algorithm shall subtype it to support
13+
[`adjust_intensity`](@ref) and [`adjust_intensity!`](@ref) APIs.
14+
15+
# Examples
16+
17+
All intensity adjustment algorithms in ImageContrastAdjustment are called in the
18+
following pattern:
19+
20+
```julia
21+
# first generate an algorithm instance
22+
f = LinearStretching()
23+
24+
# then pass the algorithm to `adjust_intensity`
25+
img_adjusted = adjust_intensity(img, f)
26+
27+
# or use in-place version `adjust_intensity!`
28+
img_adjusted = similar(img)
29+
adjust_intensity!(img_adjusted, img, f)
30+
```
31+
32+
Some algorithms also receive additional information as an argument,
33+
e.g., `gamma` of `GammaCorrection`.
34+
35+
```julia
36+
# you can explicit specify the parameters
37+
f = GammaCorrection(gamma = 1.4)
38+
```
39+
40+
For more examples, please check [`adjust_intensity`](@ref),
41+
[`adjust_intensity!`](@ref) and concrete algorithms.
42+
"""
43+
abstract type AbstractIntensityAdjustmentAlgorithm <: AbstractImageFilter end
44+
45+
adjust_intensity!(out::Union{GenericGrayImage, AbstractArray{<:Color3}},
46+
img,
47+
f::AbstractIntensityAdjustmentAlgorithm,
48+
args...; kwargs...) =
49+
f(out, img, args...; kwargs...)
50+
51+
# TODO: Relax this to all color types
52+
function adjust_intensity!(img::Union{GenericGrayImage, AbstractArray{<:Color3}},
53+
f::AbstractIntensityAdjustmentAlgorithm,
54+
args...; kwargs...)
55+
tmp = copy(img)
56+
f(img, tmp, args...; kwargs...)
57+
return img
58+
end
59+
60+
function adjust_intensity(::Type{T},
61+
img,
62+
f::AbstractIntensityAdjustmentAlgorithm,
63+
args...; kwargs...) where T
64+
out = similar(Array{T}, axes(img))
65+
adjust_intensity!(out, img, f, args...; kwargs...)
66+
return out
67+
end
68+
69+
adjust_intensity(img::AbstractArray{T},
70+
f::AbstractIntensityAdjustmentAlgorithm,
71+
args...; kwargs...) where T <: Colorant =
72+
adjust_intensity(T, img, f, args...; kwargs...)
73+
74+
# Do not promote Number to Gray{<:Number}
75+
adjust_intensity(img::AbstractArray{T},
76+
f::AbstractIntensityAdjustmentAlgorithm,
77+
args...; kwargs...) where T <: Number =
78+
adjust_intensity(T, img, f, args...; kwargs...)
79+
80+
81+
# Handle instance where the input is a sequence of images.
82+
adjust_intensity!(out_sequence::Vector{T},
83+
img_sequence,
84+
f::AbstractIntensityAdjustmentAlgorithm,
85+
args...; kwargs...) where T <: Union{GenericGrayImage, AbstractArray{<:Color3}} =
86+
f(out_sequence, img_sequence, args...; kwargs...)
87+
88+
# TODO: Relax this to all color types
89+
function adjust_intensity!(img_sequence::Vector{T},
90+
f::AbstractIntensityAdjustmentAlgorithm,
91+
args...; kwargs...) where T <: Union{GenericGrayImage, AbstractArray{<:Color3}}
92+
tmp = copy(img_sequence)
93+
f(img_sequence, tmp, args...; kwargs...)
94+
return img_sequence
95+
end
96+
97+
function adjust_intensity(::Type{T},
98+
img_sequence::Vector{<:AbstractArray},
99+
f::AbstractIntensityAdjustmentAlgorithm,
100+
args...; kwargs...) where T
101+
N = length(img_sequence)
102+
out_sequence = [similar(Array{T}, axes(img_sequence[n])) for n = 1:N]
103+
adjust_intensity!(out_sequence, img_sequence, f, args...; kwargs...)
104+
return out_sequence
105+
end
106+
107+
adjust_intensity(img_sequence::Vector{<:AbstractArray{T}},
108+
f::AbstractIntensityAdjustmentAlgorithm,
109+
args...; kwargs...) where T <: Colorant =
110+
adjust_intensity(T, img_sequence, f, args...; kwargs...)
111+
112+
# Do not promote Number to Gray{<:Number}
113+
adjust_intensity(img_sequence::Vector{<:AbstractArray{T}},
114+
f::AbstractIntensityAdjustmentAlgorithm,
115+
args...; kwargs...) where T <: Number =
116+
adjust_intensity(T, img_sequence, f, args...; kwargs...)
117+
118+
### Docstrings
119+
120+
"""
121+
adjust_intensity!([out,] img, f::AbstractIntensityAdjustmentAlgorithm, args...; kwargs...)
122+
123+
Adjust intensity of `img` using algorithm `f`.
124+
125+
# Output
126+
127+
If `out` is specified, it will be changed in place. Otherwise `img` will be changed in place.
128+
129+
# Examples
130+
131+
Just simply pass an algorithm to `adjust_intensity!`:
132+
133+
```julia
134+
img_adjusted = similar(img)
135+
adjust_intensity!(img_adjusted, img, f)
136+
```
137+
138+
For cases you just want to change `img` in place, you don't necessarily need to manually
139+
allocate `img_adjusted`; just use the convenient method:
140+
141+
```julia
142+
adjust_intensity!(img, f)
143+
```
144+
145+
See also: [`adjust_intensity`](@ref)
146+
"""
147+
adjust_intensity!
148+
149+
"""
150+
adjust_intensity([T::Type,] img, f::AbstractIntensityAdjustmentAlgorithm, args...; kwargs...)
151+
152+
Adjust intensity of `img` using algorithm `f`.
153+
154+
# Output
155+
156+
The return image `img_adjusted` is an `Array{T}`.
157+
158+
If `T` is not specified, then it's inferred.
159+
# Examples
160+
161+
Just simply pass the input image and algorithm to `adjust_intensity`
162+
163+
```julia
164+
img_adjusted = adjust_intensity(img, f)
165+
```
166+
167+
This reads as "`adjust_intensity` of image `img` using algorithm `f`".
168+
169+
You can also explicitly specify the return type:
170+
171+
```julia
172+
img_adjusted_float32 = adjust_intensity(Gray{Float32}, img, f)
173+
```
174+
175+
See also [`adjust_intensity!`](@ref) for in-place intensity adjustment.
176+
"""
177+
adjust_intensity

src/ImageContrastAdjustment.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ using ImageCore.MappedArrays
77
using Parameters: @with_kw # Same as Base.@kwdef but works on Julia 1.0
88

99
# TODO: port HistogramAdjustmentAPI to ImagesAPI
10-
include("HistogramAdjustmentAPI/HistogramAdjustmentAPI.jl")
11-
import .HistogramAdjustmentAPI: AbstractHistogramAdjustmentAlgorithm,
12-
adjust_histogram, adjust_histogram!
10+
include("ContrastAdjustmentAPI/ContrastAdjustmentAPI.jl")
11+
import .ContrastAdjustmentAPI: AbstractHistogramAdjustmentAlgorithm,
12+
adjust_histogram, adjust_histogram!,
13+
AbstractIntensityAdjustmentAlgorithm,
14+
adjust_intensity, adjust_intensity!
1315

1416
# TODO Relax this to all image color types
1517
const GenericGrayImage = AbstractArray{<:Union{Number, AbstractGray}}
@@ -37,6 +39,8 @@ export
3739
ContrastStretching,
3840
build_histogram,
3941
adjust_histogram,
40-
adjust_histogram!
42+
adjust_histogram!,
43+
adjust_intensity,
44+
adjust_intensity!
4145

4246
end # module

0 commit comments

Comments
 (0)