Function References
General function
ImageBinarization.BinarizationAPI.binarize
— Functionbinarize([T::Type,] img, f::AbstractImageBinarizationAlgorithm, args...; kwargs...)
Binarize img
using algorithm f
.
Output
The return image img₀₁
is an Array{T}
.
If T
is not specified, then it's inferred as Gray{eltype(eltype(img))}
, which is Gray{N0f8}
for img of type Array{N0f8}
and Array{Gray{N0f8}}
, and Gray{Float32}
for img of type Array{Float32}
and Array{Gray{Float32}}
Examples
Just simply pass the input image and algorithm to binarize
img₀₁ = binarize(img, f)
This reads as "binarize
image img
using binarization algorithm f
".
You can also explicitly specify the return type:
img₀₁_float32 = binarize(Gray{Float32}, img, f)
See also binarize!
for in-place binarization.
ImageBinarization.BinarizationAPI.binarize!
— Functionbinarize!([out,] img, f::AbstractImageBinarizationAlgorithm, args...; kwargs...)
Binarize img
using algorithm f
.
Output
If out
is specified, it will be changed in place. Otherwise img
will be changed in place.
Examples
Just simply pass an algorithm to binarize!
:
img₀₁ = similar(img)
binarize!(img₀₁, img, f)
For cases you just want to change img
in place, you don't necessarily need to manually allocate img₀₁
; just use the convenient method:
binarize!(img, f)
See also: binarize
Algorithms
ImageBinarization.BinarizationAPI.AbstractImageBinarizationAlgorithm
— TypeAbstractImageBinarizationAlgorithm <: AbstractImageFilter
The root type for ImageBinarization
package.
Any concrete binarization algorithm shall subtype it to support binarize
and binarize!
APIs.
Examples
All algorithms in ImageBinarization are called in the following pattern:
# first generate an algorithm instance
f = Otsu()
# then pass the algorithm to `binarize`
img₀₁ = binarize(img, f) # `eltype(img₀₁)` is `Gray{N0f8}`
# or use in-place version `binarize!`
img₀₁ = similar(img)
binarize!(img₀₁, img, f)
Some algorithms also receive additional information of image as an argument to infer the "best" parameters, e.g., window_size
of AdaptiveThreshold
.
# you could explicit specify the it
f = AdaptiveThreshold(window_size = 32)
# or infer the "best" default value from given image
img = testimage("cameraman")
f = AdaptiveThreshold(img)
For more examples, please check binarize
and binarize!
and concret algorithms.
Adaptive Threshold
ImageBinarization.AdaptiveThreshold
— TypeAdaptiveThreshold <: AbstractImageBinarizationAlgorithm
AdaptiveThreshold([img]; [window_size,] percentage = 15)
binarize([T,] img, f::AdaptiveThreshold)
binarize!([out,] img, f::AdaptiveThreshold)
Binarize img
using a threshold that varies according to background illumination.
Output
Return the binarized image as an Array{Gray{T}}
of size size(img)
. If T
is not specified, it is inferred from out
and img
.
Extended help
Details
If the value of a pixel is t
percent less than the average of an $s \times s$ window of pixels centered around the pixel, then the pixel is set to black, otherwise it is set to white.
A computationally efficient method for computing the average of an $s \times s$ neighbourhood is achieved by using an integral image integral_image
.
This algorithm works particularly well on images that have distinct contrast between background and foreground. See [1] for more details.
Arguments
The function argument is described in more detail below.
img::AbstractArray
The image that need to be binarized. The image is automatically converted to Gray
in order to construct the requisite graylevel histogram.
You can also pass img
to AdaptiveThreshold
to automatically infer the "best" window_size
.
Options
Various options for the parameters of AdaptiveThreshold
, binarize
and binarize!
are described in more detail below.
Choices for percentage
You can specify an integer for the percentage
(denoted by t
in [1]) which must be between 0 and 100. Default: 15
Choices for window_size
The argument window_size
(denoted by s
in [1]) specifies the size of pixel's square neighbourhood which must be greater than zero.
If img
is passed to AdaptiveThreshold
constructor, then window_size
is infered as the integer closest to 1/8 of the average of the width and height of img
.
Examples
using TestImages
img = testimage("cameraman")
f = AdaptiveThreshold(window_size = 16)
img₀₁ = binarize(img, f)
f = AdaptiveThreshold(img) # infer the best `window_size` using `img`
img₀₁ = binarize(img, f)
See also binarize!
for in-place operation.
References
[1] Bradley, D. (2007). Adaptive Thresholding using Integral Image. Journal of Graphic Tools, 12(2), pp.13-21. doi:10.1080/2151237x.2007.10129236
Niblack
ImageBinarization.Niblack
— TypeNiblack <: AbstractImageBinarizationAlgorithm
Niblack(; window_size = 7, bias = 0.2)
binarize([T,] img, f::Niblack)
binarize!([out,] img, f::Niblack)
Applies Niblack adaptive thresholding [1] under the assumption that the input image is textual.
Output
Return the binarized image as an Array{Gray{T}}
of size size(img)
. If T
is not specified, it is inferred from out
and img
.
Extended help
Details
The input image is binarized by varying the threshold across the image, using a modified version of Niblack's algorithm [2]. A threshold $T$ is defined for each pixel based on the mean $m$ and standard deviation $s$ of the intensities of neighboring pixels in a window around it. This threshold is given by
\[T(x,y) = m(x,y) + k \cdot s(x,y),\]
where $k$ is a user-defined parameter weighting the influence of the standard deviation on the value of $T$.
Note that Niblack's algorithm is highly sensitive to variations in the gray values of background pixels, which often exceed local thresholds and appear as artifacts in the binarized image. The Sauvola
algorithm included in this package implements an attempt to address this issue [2].
Arguments
img
An image which is binarized according to a per-pixel adaptive threshold into background (0) and foreground (1) pixel values.
bias::Real
(denoted by $k$ in the publication)
A user-defined biasing parameter on threshold. This can take negative values. Larger bias
encourages more black pixels in the output.
window_size::Integer
(denoted by $w$ in the publication)
The threshold for each pixel is a function of the distribution of the intensities of all neighboring pixels in a square window around it. The side length of this window is $2w + 1$, with the target pixel in the center position.
If not specified, window_size
is 7
.
Example
Binarize the "cameraman" image in the TestImages
package.
using TestImages, ImageBinarization
img = testimage("cameraman")
img₀₁ = binarize(img, Niblack())
References
[1] Wayne Niblack (1986). An Introduction to Image Processing. Prentice-Hall, Englewood Cliffs, NJ: 115-16. [2] J. Sauvola and M. Pietikäinen (2000). "Adaptive document image binarization". Pattern Recognition 33 (2): 225-236. doi:10.1016/S0031-3203(99)00055-2
Polysegment
ImageBinarization.Polysegment
— TypePolysegment <: AbstractImageBinarizationAlgorithm
Polysegment()
binarize([T,] img, f::Polysegment)
binarize!([out,] img, f::Polysegment)
Uses the polynomial segmentation technique to group the image pixels into two categories (foreground and background).
Output
Return the binarized image as an Array{Gray{T}}
of size size(img)
. If T
is not specified, it is inferred from out
and img
.
Extended help
Details
The approach involves constructing a univariate second-degree polynomial such that the two roots of the polynomial represent the graylevels of two cluster centers (i.e the foreground and background). Pixels are then assigned to the foreground or background depending on which cluster center is closest.
Arguments
The function argument is described in more detail below.
img::AbstractArray
The image that needs to be binarized. The image is automatically converted to Gray
.
Example
Binarize the "cameraman" image in the TestImages
package.
using TestImages, ImageBinarization
img = testimage("cameraman")
img_binary = binarize(img, Polysegment())
Reference
- R. E. Vidal, "Generalized Principal Component Analysis (GPCA): An Algebraic Geometric Approach to Subspace Clustering and Motion Segmentation." Order No. 3121739, University of California, Berkeley, Ann Arbor, 2003.
Sauvola
ImageBinarization.Sauvola
— TypeSauvola <: AbstractImageBinarizationAlgorithm
Sauvola(; bias = 0.2, window_size=7)
binarize([T,] img, f::Sauvola)
binarize!([out,] img, f::Sauvola)
Applies Sauvola–Pietikäinen adaptive image binarization [1] under the assumption that the input image is textual.
Output
Return the binarized image as an Array{Gray{T}}
of size size(img)
. If T
is not specified, it is inferred from out
and img
.
Extended help
Details
The input image is binarized by varying the threshold across the image, using a modified version of Niblack's algorithm [2]. Niblack's approach was to define a threshold $T$ for each pixel based on the mean $m$ and standard deviation $s$ of the intensities of neighboring pixels in a window around it, given by
\[T(x,y) = m(x,y) + k \cdot s(x,y),\]
where $k$ is a user-defined parameter weighting the influence of the standard deviation on the value of $T$.
Niblack's algorithm is highly sensitive to variations in the gray values of background pixels, which often exceed local thresholds and appear as artifacts in the binarized image. Sauvola and Pietikäinen [1] introduce the dynamic range $R$ of the standard deviation (i.e. its maximum possible value in the color space), such that the threshold is given by
\[T(x,y) = m(x,y) \cdot \left[ 1 + k \cdot \left( \frac{s(x,y)}{R} - 1 \right) \right]\]
This adaptively amplifies the contribution made by the standard deviation to the value of $T$.
The Sauvola–Pietikäinen algorithm is implemented here using an optimization proposed by Shafait, Keysers and Breuel [3], in which integral images are used to calculate the values of $m$ and $s$ for each pixel in constant time. Since each of these data structures can be computed in a single pass over the source image, runtime is significantly improved.
Arguments
img
An image which is binarized according to a per-pixel adaptive threshold into background (0) and foreground (1) pixel values.
window_size::Integer
(denoted by $w$ in the publication)
The threshold for each pixel is a function of the distribution of the intensities of all neighboring pixels in a square window around it. The side length of this window is $2w + 1$, with the target pixel in the center position.
bias::Real
(denoted by $k$ in the publication)
A user-defined biasing parameter. This can take negative values, though values in the range [0.2, 0.5] are typical. According to [1], this algorithm is not too sensitive to the value of $k$`.
Example
Binarize the "cameraman" image in the TestImages
package.
using TestImages, ImageBinarization
img = testimage("cameraman")
img_binary = binarize(img, Sauvola(window_size = 9, bias = 0.2))
References
- J. Sauvola and M. Pietikäinen (2000). "Adaptive document image binarization". Pattern Recognition 33 (2): 225-236. doi:10.1016/S0031-3203(99)00055-2
- Wayne Niblack (1986). An Introduction to Image Processing. Prentice-Hall, Englewood Cliffs, NJ: 115-16.
- Faisal Shafait, Daniel Keysers and Thomas M. Breuel (2008). "Efficient implementation of local adaptive thresholding techniques using integral images". Proc. SPIE 6815, Document Recognition and Retrieval XV, 681510 (28 January 2008). doi:10.1117/12.767755
Algorithms that utilizes single histogram-threshold
The core functionality of these algorithms are supported by HistogramThresholding.jl
ImageBinarization.SingleHistogramThreshold
— TypeSingleHistogramThreshold <: AbstractImageBinarizationAlgorithm
SingleHistogramThreshold(alg::AbstractThresholdAlgorithm; nbins=256)
binarize([T,] img, f::AbstractThresholdAlgorithm; nbins=256)
binarize!([out,] img, f::AbstractThresholdAlgorithm; nbins=256)
Binarizes the image img
using the threshold found by given threshold finding algorithm alg
.
Output
Return the binarized image as an Array{Gray{T}}
of size size(img)
. If T
is not specified, it is inferred from out
and img
.
Arguments
The function argument is described in more detail below.
img::AbstractArray
The image that needs to be binarized. The image is automatically converted to Gray
in order to construct the requisite graylevel histogram.
alg::AbstractThresholdAlgorithm
AbstractThresholdAlgorithm
is an abstract type defined in ThresholdAPI.jl
in the HistogramThreshold.jl
package, it provides various threshold finding algorithms:
HistogramThresholding.Balanced
HistogramThresholding.Entropy
HistogramThresholding.Intermodes
HistogramThresholding.MinimumError
HistogramThresholding.MinimumIntermodes
HistogramThresholding.Moments
HistogramThresholding.Otsu
HistogramThresholding.UnimodalRosin
HistogramThresholding.Yen
For the more detailed explaination and the construction, please refer to each concrete algorithm. For example, type ?Otsu
in REPL will give you more details on how to use Otsu
methods.
nbins::Integer
The number of discrete bins that used to build the histogram. A smaller nbins
could possibly gives a less noisy, or in other words, a smoother output. The default value is 256
.
Examples
All the usage follows the same pattern, take Otsu
as an example:
using TestImages, ImageBinarization
img = testimage("cameraman")
img_binary = binarize(img, Otsu())
It is less convenient, but still, you could also construct a SingleHistogramThreshold
by yourself:
using TestImages, ImageBinarization
img = testimage("cameraman")
f = SingleHistogramThreshold(Otsu(), nbins=256)
img_binary = binarize(img, f)
Otsu
HistogramThresholding.Otsu
— Typet = find_threshold(histogram, edges, Otsu())
t = find_threshold(img, Otsu(); nbins = 256)
Under the assumption that the histogram is bimodal the threshold is set so that the resultant between-class variance is maximal.
Output
Returns a real number t
in edges
. The edges
parameter represents an AbstractRange
which specifies the intervals associated with the histogram bins.
Extended help
Details
Let $f_i$ $(i=1 \ldots I)$ denote the number of observations in the $i$th bin of the histogram. Then the probability that an observation belongs to the $i$th bin is given by $p_i = \frac{f_i}{N}$ ($i = 1, \ldots, I$), where $N = \sum_{i=1}^{I}f_i$.
The choice of a threshold $T$ partitions the data into two categories, $C_0$ and $C_1$. Let
\[P_0(T) = \sum_{i = 1}^T p_i \quad \text{and} \quad P_1(T) = \sum_{i = T+1}^I p_i\]
denote the cumulative probabilities,
\[\mu_0(T) = \sum_{i = 1}^T i \frac{p_i}{P_0(T)} \quad \text{and} \quad \mu_1(T) = \sum_{i = T+1}^I i \frac{p_i}{P_1(T)}\]
denote the means, and
\[\sigma_0^2(T) = \sum_{i = 1}^T (i-\mu_0(T))^2 \frac{p_i}{P_0(T)} \quad \text{and} \quad \sigma_1^2(T) = \sum_{i = T+1}^I (i-\mu_1(T))^2 \frac{p_i}{P_1(T)}\]
denote the variances of categories $C_0$ and $C_1$, respectively. Furthermore, let
\[\mu = P_0(T)\mu_0(T) + P_1(T)\mu_1(T),\]
represent the overall mean,
\[\sigma_b^2(T) = P_0(T)(\mu_0(T) - \mu)^2 + P_1(T)(\mu_1(T) - \mu)^2,\]
the between-category variance, and
\[\sigma_w^2(T) = P_0(T) \sigma_0^2(T) + P_1(T)\sigma_1^2(T)\]
the within-category variance, respectively.
Finding the discrete value $T$ which maximises the function $\sigma_b^2(T)$ produces the sought-after threshold value (i.e. the bin which determines the threshold). As it turns out, that threshold value is equal to the threshold decided by minimizing the within-category variances criterion $\sigma_w^2(T)$. Furthermore, that threshold is also the same as the threshold calculated by maximizing the ratio of between-category variance to within-category variance.
Arguments
The function arguments are described in more detail below.
histogram
An AbstractArray
storing the frequency distribution.
edges
An AbstractRange
specifying how the intervals for the frequency distribution are divided.
Example
Compute the threshold for the "cameraman" image in the TestImages
package.
using TestImages, ImageContrastAdjustment, HistogramThresholding
img = testimage("cameraman")
edges, counts = build_histogram(img,256)
#=
The `counts` array stores at index 0 the frequencies that were below the
first bin edge. Since we are seeking a threshold over the interval
partitioned by `edges` we need to discard the first bin in `counts`
so that the dimensions of `edges` and `counts` match.
=#
t = find_threshold(counts[1:end], edges, Otsu())
Reference
- Nobuyuki Otsu (1979). “A threshold selection method from gray-level histograms”. IEEE Trans. Sys., Man., Cyber. 9 (1): 62–66. doi:10.1109/TSMC.1979.4310076
MinimumIntermodes
HistogramThresholding.MinimumIntermodes
— Typet = find_threshold(histogram, edges, Minimum(); maxiter = 8000)
t = find_threshold(img, Minimum(); nbins = 256)
Under the assumption that the histogram is bimodal the histogram is smoothed using a length-3 mean filter until two modes remain. The threshold is then set to the minimum value between the two modes.
Output
Returns a real number t
in edges
. The edges
parameter represents an AbstractRange
which specifies the intervals associated with the histogram bins.
Extended help
Details
If after maxiter
iterations the smoothed histogram is still not bimodal then the algorithm will fall back to using the UnimodalRosin
method to select a threshold.
Arguments
The function arguments are described in more detail below.
histogram
An AbstractArray
storing the frequency distribution.
edges
An AbstractRange
specifying how the intervals for the frequency distribution are divided.
maxiter
An Int
that specifies the maximum number of smoothing iterations. If left unspecified a default value of 8000 is used.
Example
Compute the threshold for the "cameraman" image in the TestImages
package.
using TestImages, ImageContrastAdjustment, HistogramThresholding
img = testimage("cameraman")
edges, counts = build_histogram(img,256)
#=
The `counts` array stores at index 0 the frequencies that were below the
first bin edge. Since we are seeking a threshold over the interval
partitioned by `edges` we need to discard the first bin in `counts`
so that the dimensions of `edges` and `counts` match.
=#
t = find_threshold(counts[1:end], edges, MinimumIntermodes())
Reference
- C. A. Glasbey, “An Analysis of Histogram-Based Thresholding Algorithms,” CVGIP: Graphical Models and Image Processing, vol. 55, no. 6, pp. 532–537, Nov. 1993. doi:10.1006/cgip.1993.1040
- J. M. S. Prewitt and M. L. Mendelsohn, “THE ANALYSIS OF CELL IMAGES,” *Annals of the New York Academy of Sciences, vol. 128, no. 3, pp. 1035–1053, Dec. 2006. doi:10.1111/j.1749-6632.1965.tb11715.x
Intermodes
HistogramThresholding.Intermodes
— Typet = find_threshold(histogram, edges, Intermodes(maxiter=8000))
t = find_threshold(img, Intermodes(); nbins = 256)
Under the assumption that the histogram is bimodal the histogram is smoothed using a length-3 mean filter until two modes remain. The threshold is then set to the average value of the two modes.
Output
Returns a real number t
in edges
. The edges
parameter represents an AbstractRange
which specifies the intervals associated with the histogram bins.
Extended help
Details
If after maxiter
iterations the smoothed histogram is still not bimodal then the algorithm will fall back to using the UnimodalRosin
method to select a threshold.
Arguments
The function arguments are described in more detail below.
histogram
An AbstractArray
storing the frequency distribution.
edges
An AbstractRange
specifying how the intervals for the frequency distribution are divided.
maxiter
An Int
that specifies the maximum number of smoothing iterations. If left unspecified a default value of 1000 is used.
Example
Compute the threshold for the "cameraman" image in the TestImages
package.
using TestImages, ImageContrastAdjustment, HistogramThresholding
img = testimage("cameraman")
edges, counts = build_histogram(img,256)
#=
The `counts` array stores at index 0 the frequencies that were below the
first bin edge. Since we are seeking a threshold over the interval
partitioned by `edges` we need to discard the first bin in `counts`
so that the dimensions of `edges` and `counts` match.
=#
t = find_threshold(counts[1:end], edges, Intermodes())
Reference
- C. A. Glasbey, “An Analysis of Histogram-Based Thresholding Algorithms,” CVGIP: Graphical Models and Image Processing, vol. 55, no. 6, pp. 532–537, Nov. 1993. doi:10.1006/cgip.1993.1040
MinimumError
HistogramThresholding.MinimumError
— Typet = find_threshold(histogram, edges, MinimumError())
t = find_threshold(img, MinimumError(); nbins = 256)
Under the assumption that the histogram is a mixture of two Gaussian distributions the threshold is chosen such that the expected misclassification error rate is minimised.
Output
Returns a real number t
in edges
. The edges
parameter represents an AbstractRange
which specifies the intervals associated with the histogram bins.
Extended help
Details
Let $f_i$ $(i=1 \ldots I)$ denote the number of observations in the $i$th bin of the histogram. Then the probability that an observation belongs to the $i$th bin is given by $p_i = \frac{f_i}{N}$ ($i = 1, \ldots, I$), where $N = \sum_{i=1}^{I}f_i$.
The minimum error thresholding method assumes that one can find a threshold $T$ which partitions the data into two categories, $C_0$ and $C_1$, such that the data can be modelled by a mixture of two Gaussian distribution. Let
\[P_0(T) = \sum_{i = 1}^T p_i \quad \text{and} \quad P_1(T) = \sum_{i = T+1}^I p_i\]
denote the cumulative probabilities,
\[\mu_0(T) = \sum_{i = 1}^T i \frac{p_i}{P_0(T)} \quad \text{and} \quad \mu_1(T) = \sum_{i = T+1}^I i \frac{p_i}{P_1(T)}\]
denote the means, and
\[\sigma_0^2(T) = \sum_{i = 1}^T (i-\mu_0(T))^2 \frac{p_i}{P_0(T)} \quad \text{and} \quad \sigma_1^2(T) = \sum_{i = T+1}^I (i-\mu_1(T))^2 \frac{p_i}{P_1(T)}\]
denote the variances of categories $C_0$ and $C_1$, respectively.
Kittler and Illingworth proposed to use the minimum error criterion function
\[J(T) = 1 + 2 \left[ P_0(T) \ln \sigma_0(T) + P_1(T) \ln \sigma_1(T) \right] - 2 \left[P_0(T) \ln P_0(T) + P_1(T) \ln P_1(T) \right]\]
to assess the discreprancy between the mixture of Gaussians implied by a particular threshold $T$, and the piecewise-constant probability density function represented by the histogram. The discrete value $T$ which minimizes the function $J(T)$ produces the sought-after threshold value (i.e. the bin which determines the threshold).
Arguments
The function arguments are described in more detail below.
histogram
An AbstractArray
storing the frequency distribution.
edges
An AbstractRange
specifying how the intervals for the frequency distribution are divided.
Example
Compute the threshold for the "cameraman" image in the TestImages
package.
using TestImages, ImageContrastAdjustment, HistogramThresholding
img = testimage("cameraman")
edges, counts = build_histogram(img,256)
#=
The `counts` array stores at index 0 the frequencies that were below the
first bin edge. Since we are seeking a threshold over the interval
partitioned by `edges` we need to discard the first bin in `counts`
so that the dimensions of `edges` and `counts` match.
=#
t = find_threshold(counts[1:end], edges, MinimumError())
References
- J. Kittler and J. Illingworth, “Minimum error thresholding,” Pattern Recognition, vol. 19, no. 1, pp. 41–47, Jan. 1986. doi:10.1016/0031-3203(86)90030-0
- Q.-Z. Ye and P.-E. Danielsson, “On minimum error thresholding and its implementations,” Pattern Recognition Letters, vol. 7, no. 4, pp. 201–206, Apr. 1988. doi:10.1016/0167-8655(88)90103-1
Moments
HistogramThresholding.Moments
— Typet = find_threshold(histogram, edges, Moments())
t = find_threshold(img, Moments(); nbins = 256)
The following rule determines the threshold: if one assigns all observations below the threshold to a value z₀ and all observations above the threshold to a value z₁, then the first three moments of the original histogram must match the moments of this specially constructed bilevel histogram.
Output
Returns a real number t
in edges
. The edges
parameter represents an AbstractRange
which specifies the intervals associated with the histogram bins.
Extended help
Details
Let $f_i$ $(i=1 \ldots I)$ denote the number of observations in the $i$th bin of the histogram and $z_i$ $(i=1 \ldots I)$ the observed value associated with the $i$th bin. Then the probability that an observation $z_i$ belongs to the $i$th bin is given by $p_i = \frac{f_i}{N}$ ($i = 1, \ldots, I$), where $N = \sum_{i=1}^{I}f_i$.
Moments can be computed from the histogram $f$ in the following way:
\[m_k = \frac{1}{N} \sum_i p_i (z_i)^k \quad k = 0,1,2,3, \ldots.\]
The principle of moment-preserving thresholding is to select a threshold value, as well as two representative values $z_0$ and $z_1$ ($z_0 < z_1$), such that if all below-threshold values in $f$ are replaced by $z_0$ and all above-threshold values are replaced by $z_1$, then this specially constructed bilevel histogram $g$ will have the same first three moments as $f$.
Concretely, let $q_0$ and $q_1$ denote the fractions of observations below and above the threshold in $f$, respectively. The constraint that the first three moments in $g$ must equal the first three moments in $f$ can be expressed by the following system of four equations
\[\begin{aligned} q_0 (z_0)^0 + q_1 (z_1)^0 & = m_0 \\ q_0 (z_0)^1 + q_1 (z_1)^1 & = m_1 \\ q_0 (z_0)^2 + q_1 (z_1)^2 & = m_2 \\ q_0 (z_0)^3 + q_1 (z_1)^3 & = m_3 \\ \end{aligned}\]
where the left-hand side represents the moments of $g$ and the right-hand side represents the moments of $f$. To find the desired treshold value, one first solves the four equations to obtain $q_0$ and $q_1$, and then chooses the threshold $t$ such that $q_0 = \sum_{z_i \le t} p_i$.
Arguments
The function arguments are described in more detail below.
histogram
An AbstractArray
storing the frequency distribution.
edges
An AbstractRange
specifying how the intervals for the frequency distribution are divided.
Example
Compute the threshold for the "cameraman" image in the TestImages
package.
using TestImages, ImageContrastAdjustment, HistogramThresholding
img = testimage("cameraman")
edges, counts = build_histogram(img,256)
#=
The `counts` array stores at index 0 the frequencies that were below the
first bin edge. Since we are seeking a threshold over the interval
partitioned by `edges` we need to discard the first bin in `counts`
so that the dimensions of `edges` and `counts` match.
=#
t = find_threshold(counts[1:end], edges, Moments())
Reference
[1] W.-H. Tsai, “Moment-preserving thresolding: A new approach,” Computer Vision, Graphics, and Image Processing, vol. 29, no. 3, pp. 377–393, Mar. 1985. doi:10.1016/0734-189x(85)90133-1
UnimodalRosin
HistogramThresholding.UnimodalRosin
— Typet = find_threshold(histogram, edges, UnimodalRosin())
t = find_threshold(img, UnimodalRosin(); nbins = 256)
Generates a threshold assuming a unimodal distribution using Rosin's algorithm.
Output
Returns a real number t
in edges
. The edges
parameter represents an AbstractRange
which specifies the intervals associated with the histogram bins.
Extended help
Details
This algorithm first selects the bin in the histogram with the highest frequency. The algorithm then searches from the location of the maximum bin to the last bin of the histogram for the first bin with a frequency of 0 (known as the minimum bin.). A line is then drawn that passes through both the maximum and minimum bins. The bin with the greatest orthogonal distance to the line is chosen as the threshold value.
Assumptions
This algorithm assumes that:
- The histogram is unimodal.
- There is always at least one bin that has a frequency of 0. If not, the algorithm will use the last bin as the minimum bin.
If the histogram includes multiple bins with a frequency of 0, the algorithm will select the first zero bin as its minimum. If there are multiple bins with the greatest orthogonal distance, the leftmost bin is selected as the threshold.
Arguments
The function arguments are described in more detail below.
histogram
An AbstractArray
storing the frequency distribution.
edges
An AbstractRange
specifying how the intervals for the frequency distribution are divided.
Example
Compute the threshold for the "moonsurface" image in the TestImages
package.
using TestImages, ImageContrastAdjustment, HistogramThresholding
img = testimage("moonsurface")
edges, counts = build_histogram(img,256)
#=
The `counts` array stores at index 0 the frequencies that were below the
first bin edge. Since we are seeking a threshold over the interval
partitioned by `edges` we need to discard the first bin in `counts`
so that the dimensions of `edges` and `counts` match.
=#
t = find_threshold(counts[1:end], edges, UnimodalRosin())
Reference
- P. L. Rosin, “Unimodal thresholding,” Pattern Recognition, vol. 34, no. 11, pp. 2083–2096, Nov. 2001.doi:10.1016/s0031-3203(00)00136-9
Entropy
HistogramThresholding.Entropy
— Typefind_threshold(counts, edges, Entropy())
t = find_threshold(img, Entropy(); nbins = 256)
An algorithm for finding the threshold value for a gray-level histogram using the entropy of the histogram.
Output
Returns the point in the AbstractRange
which corresponds to the threshold bin in the histogram.
Extended help
Details
This algorithm uses the entropy of a gray level histogram to produce a threshold value.
Let $f_1, f_2, \ldots, f_I$ be the frequencies in the various bins of the histogram and $I$ the number of bins. With $N = \sum_{i=1}^{I}f_i$, let $p_i = \frac{f_i}{N}$ ($i = 1, \ldots, I$) denote the probability distribution of gray levels. From this distribution one derives two additional distributions. The first defined for discrete values $1$ to $s$ and the other, from $s+1$ to $I$. These distributions are
\[A: \frac{p_1}{P_s}, \frac{p_2}{P_s}, \ldots, \frac{p_s}{P_s} \quad \text{and} \quad B: \frac{p_{s+1}}{1-P_s}, \ldots, \frac{p_n}{1-P_s} \quad \text{where} \quad P_s = \sum_{i=1}^{s}p_i.\]
The entropies associated with each distribution are as follows:
\[H(A) = \ln(P_s) + \frac{H_s}{P_s}\]
\[H(B) = \ln(1-P_s) + \frac{H_n-H_s}{1-P_s}\]
\[\quad \text{where} \quad H_s = -\sum_{i=1}^{s}p_i\ln{p_i} \quad \text{and} \quad H_n = -\sum_{i=1}^{I}p_i\ln{p_i}.\]
Combining these two entropy functions we have
\[\psi(s) = \ln(P_s(1-P_s)) + \frac{H_s}{P_s} + \frac{H_n-H_s}{1-P_s}.\]
Finding the discrete value $s$ which maximises the function $\psi(s)$ produces the sought-after threshold value (i.e. the bin which determines the threshold).
See Section 4 of [1] for more details on the derivation of the entropy.
Options
Choices for counts
You can specify an AbstractArray
which should be a 1D array of frequencies for a histogram. You should submit the corresponding edges
range for the bins of the histogram. The function will throw an error if it detects that the edges
and counts
have different lengths.
Choices for edges
You can specify an AbstractRange
which should be the corresponding range for the bins of the histogram array passed into counts
.
Example
using TestImages, Images
img = testimage("cameraman")
# building a histogram with 256 bins
edges, counts = build_histogram(img, 256)
#=
The `counts` array stores at index 0 the frequencies that were below the
first bin edge. Since we are seeking a threshold over the interval
partitioned by `edges` we need to discard the first bin in `counts`
so that the dimensions of `edges` and `counts` match.
=#
find_threshold(counts[1:end], edges, Entropy())
References
[1] J. N. Kapur, P. K. Sahoo, and A. K. C. Wong, “A new method for gray-level picture thresholding using the entropy of the histogram,” Computer Vision, Graphics, and Image Processing, vol. 29, no. 1, p. 140, Jan. 1985.doi:10.1016/s0734-189x(85)90156-2
Balanced
HistogramThresholding.Balanced
— Typet = find_threshold(histogram, edges, Balanced())
t = find_threshold(img, Balanced(); nbins = 256)
In balanced histogram thresholding, one interprets a bin as a physical weight with a mass equal to its occupancy count. The balanced histogram method involves iterating the following three steps: (1) choose the midpoint bin index as a "pivot", (2) compute the combined weight to the left and right of the pivot bin and (3) remove the leftmost bin if the left side is the heaviest, and the rightmost bin otherwise. The algorithm stops when only a single bin remains. The last bin determines the sought-after threshold.
Output
Returns a real number t
in edges
. The edges
parameter represents an AbstractRange
which specifies the intervals associated with the histogram bins.
Extended help
Details
Let $f_n$ ($n = 1 \ldots N$) denote the number of observations in the $n$th bin of the histogram. The balanced histogram method constructs a sequence of nested intervals
\[[1,N] \cap \mathbb{Z} \supset I_2 \supset I_3 \supset \ldots \supset I_{N-1},\]
where for $k = 2 \ldots N-1$
\[I_k = \begin{cases} I_{k-1} \setminus \{\min \left( I_{k-1} \right) \} &\text{if } \sum_{n = \min \left( I_{k-1} \right)}^{I_m}f_n \gt \sum_{n = I_m + 1}^{ \max \left( I_{k-1} \right)} f_n, \\ I_{k-1} \setminus \{\max \left( I_{k-1} \right) \} &\text{otherwise}, \end{cases}\]
and $I_m = \lfloor \frac{1}{2}\left( \min \left( I_{k-1} \right) + \max \left( I_{k-1} \right) \right) \rfloor$. The final interval $I_{N-1}$ consists of a single element which is the bin index corresponding to the desired threshold.
If one interprets a bin as a physical weight with a mass equal to its occupancy count, then each step of the algorithm can be conceptualised as removing the leftmost or rightmost bin to "balance" the resulting histogram on a pivot. The pivot is defined to be the midpoint between the start and end points of the interval under consideration.
If it turns out that the single element in $I_{N-1}$ equals $1$ or $N$ then the original histogram must have a single peak and the algorithm has failed to find a suitable threshold. In this case the algorithm will fall back to using the UnimodalRosin
method to select the threshold.
Arguments
The function arguments are described in more detail below.
histogram
An AbstractArray
storing the frequency distribution.
edges
An AbstractRange
specifying how the intervals for the frequency distribution are divided.
Example
Compute the threshold for the "cameraman" image in the TestImages
package.
using TestImages, ImageContrastAdjustment, HistogramThresholding
img = testimage("cameraman")
edges, counts = build_histogram(img, 256)
#=
The `counts` array stores at index 0 the frequencies that were below the
first bin edge. Since we are seeking a threshold over the interval
partitioned by `edges` we need to discard the first bin in `counts`
so that the dimensions of `edges` and `counts` match.
=#
t = find_threshold(counts[1:end], edges, Balanced())
Reference
- “BI-LEVEL IMAGE THRESHOLDING - A Fast Method”, Proceedings of the First International Conference on Bio-inspired Systems and Signal Processing, 2008. Available: 10.5220/0001064300700076
Yen
HistogramThresholding.Yen
— Typet = find_threshold(histogram, edges, Yen())
t = find_threshold(img, Yen(); nbins = 256)
Computes the threshold value using Yen's maximum correlation criterion for bilevel thresholding.
Output
Returns a real number t
in edges
. The edges
parameter represents an AbstractRange
which specifies the intervals associated with the histogram bins.
Extended help
Details
This algorithm uses the concept of entropic correlation of a gray level histogram to produce a threshold value.
Let $f_1, f_2, \ldots, f_I$ be the frequencies in the various bins of the histogram and $I$ the number of bins. With $N = \sum_{i=1}^{I}f_i$, let $p_i = \frac{f_i}{N}$ ($i = 1, \ldots, I$) denote the probability distribution of gray levels. From this distribution one derives two additional distributions. The first defined for discrete values $1$ to $s$ and the other, from $s+1$ to $I$. These distributions are
\[A: \frac{p_1}{P_s}, \frac{p_2}{P_s}, \ldots, \frac{p_s}{P_s} \quad \text{and} \quad B: \frac{p_{s+1}}{1-P_s}, \ldots, \frac{p_n}{1-P_s} \quad \text{where} \quad P_s = \sum_{i=1}^{s}p_i.\]
The entropic correlations associated with each distribution are
\[C(A) = -\ln \sum_{i=1}^{s} \left( \frac{p_i}{P_s} \right)^2 \quad \text{and} \quad C(B) = -\ln \sum_{i=s+1}^{I} \left( \frac{p_i}{1 - P_s} \right)^2.\]
Combining these two entropic correlation functions we have
\[\psi(s) = -\ln \sum_{i=1}^{s} \left( \frac{p_i}{P_s} \right)^2 -\ln \sum_{i=s+1}^{I} \left( \frac{p_i}{1 - P_s} \right)^2.\]
Finding the discrete value $s$ which maximises the function $\psi(s)$ produces the sought-after threshold value (i.e. the bin which determines the threshold).
Arguments
The function arguments are described in more detail below.
histogram
An AbstractArray
storing the frequency distribution.
edges
An AbstractRange
specifying how the intervals for the frequency distribution are divided.
Example
Compute the threshold for the "cameraman" image in the TestImages
package.
using TestImages, ImageContrastAdjustment, HistogramThresholding
img = testimage("cameraman")
edges, counts = build_histogram(img, 256)
#=
The `counts` array stores at index 0 the frequencies that were below the
first bin edge. Since we are seeking a threshold over the interval
partitioned by `edges` we need to discard the first bin in `counts`
so that the dimensions of `edges` and `counts` match.
=#
t = find_threshold(counts[1:end], edges, Yen())
Reference
- Yen JC, Chang FJ, Chang S (1995), “A New Criterion for Automatic Multilevel Thresholding”, IEEE Trans. on Image Processing 4 (3): 370-378, doi:10.1109/83.366472