Function References

General function

ImageContrastAdjustment.HistogramAdjustmentAPI.adjust_histogramFunction
adjust_histogram([T::Type,] img, f::AbstractHistogramAdjustmentAlgorithm, args...; kwargs...)

Adjust histogram of img using algorithm f.

Output

The return image img_adjusted is an Array{T}.

If T is not specified, then it's inferred.

Examples

Just simply pass the input image and algorithm to adjust_histogram

img_adjusted = adjust_histogram(img, f)

This reads as "adjust_histogram of image img using algorithm f".

You can also explicitly specify the return type:

img_adjusted_float32 = adjust_histogram(Gray{Float32}, img, f)

See also adjust_histogram! for in-place histogram adjustment.

source
ImageContrastAdjustment.HistogramAdjustmentAPI.adjust_histogram!Function
adjust_histogram!([out,] img, f::AbstractHistogramAdjustmentAlgorithm, args...; kwargs...)

Adjust histogram of 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 adjust_histogram!:

img_adjusted = similar(img)
adjust_histogram!(img_adjusted, img, f)

For cases you just want to change img in place, you don't necessarily need to manually allocate img_adjusted; just use the convenient method:

adjust_histogram!(img, f)

See also: adjust_histogram

source
ImageContrastAdjustment.build_histogramFunction
edges, count = build_histogram(img)            # For 8-bit images only
edges, count = build_histogram(img, nbins)
edges, count = build_histogram(img, nbins; minval, maxval)
edges, count = build_histogram(img, edges)

Generates a histogram for the image over nbins spread between [minval, maxval]. Color images are automatically converted to grayscale.

Output

Returns edges which is a AbstractRange type that specifies how the interval [minval, maxval] is divided into bins, and an array count which records the concomitant bin frequencies. In particular, count has the following properties:

  • count[0] is the number satisfying x < edges[1]
  • count[i] is the number of values x that satisfy edges[i] <= x < edges[i+1]
  • count[end] is the number satisfying x >= edges[end].
  • length(count) == length(edges)+1.

Details

One can consider a histogram as a piecewise-constant model of a probability density function $f$ [1]. Suppose that $f$ has support on some interval $I = [a,b]$. Let $m$ be an integer and $a = a_1 < a_2 < \ldots < a_m < a_{m+1} = b$ a sequence of real numbers. Construct a sequence of intervals

\[I_1 = [a_1,a_2], I_2 = (a_2, a_3], \ldots, I_{m} = (a_m,a_{m+1}]\]

which partition $I$ into subsets $I_j$ $(j = 1, \ldots, m)$ on which $f$ is constant. These subsets satisfy $I_i \cap I_j = \emptyset, \forall i \neq j$, and are commonly referred to as bins. Together they encompass the entire range of data values such that $\sum_j |I_j | = | I |$. Each bin has width $w_j = |I_j| = a_{j+1} - a_j$ and height $h_j$ which is the constant probability density over the region of the bin. Integrating the constant probability density over the width of the bin $w_j$ yields a probability mass of $\pi_j = h_j w_j$ for the bin.

For a sample $x_1, x_2, \ldots, x_N$, let

\[n_j = \sum_{n = 1}^{N}\mathbf{1}_{(I_j)}(x_n), \quad \text{where} \quad \mathbf{1}_{(I_j)}(x) = \begin{cases} 1 & \text{if} \; x \in I_j,\\ 0 & \text{otherwise}, \end{cases},\]

represent the number of samples falling into the interval $I_j$. An estimate for the probability mass of the $j$th bin is given by the relative frequency $\hat{\pi} = \frac{n_j}{N}$, and the histogram estimator of the probability density function is defined as

\[\begin{aligned} \hat{f}_n(x) & = \sum_{j = 1}^{m}\frac{n_j}{Nw_j} \mathbf{1}_{(I_j)}(x) \\ & = \sum_{j = 1}^{m}\frac{\hat{\pi}_j}{w_j} \mathbf{1}_{(I_j)}(x) \\ & = \sum_{j = 1}^{m}\hat{h}_j \mathbf{1}_{(I_j)}(x). \end{aligned}\]

The function $\hat{f}_n(x)$ is a genuine density estimator because $\hat{f}_n(x) \ge 0$ and

\[\begin{aligned} \int_{-\infty}^{\infty}\hat{f}_n(x) \operatorname{d}x & = \sum_{j=1}^{m} \frac{n_j}{Nw_j} w_j \\ & = 1. \end{aligned}\]

Options

Various options for the parameters of this function are described in more detail below.

Choices for nbins

You can specify the number of discrete bins for the histogram. When specifying the number of bins consider the maximum number of graylevels that your image type supports. For example, with an image of type N0f8 there is a maximum of 256 possible graylevels. Hence, if you request more than 256 bins for that type of image you should expect to obtain zero counts for numerous bins.

Choices for minval

You have the option to specify the lower bound of the interval over which the histogram will be computed. If minval is not specified then the minimum value present in the image is taken as the lower bound.

Choices for maxval

You have the option to specify the upper bound of the interval over which the histogram will be computed. If maxval is not specified then the maximum value present in the image is taken as the upper bound.

Choices for edges

If you do not designate the number of bins, nor the lower or upper bound of the interval, then you have the option to directly stipulate how the intervals will be divided by specifying a AbstractRange type.

Example

Compute the histogram of a grayscale image.


using TestImages, FileIO, ImageView

img =  testimage("mandril_gray");
edges, counts  = build_histogram(img, 256, minval = 0, maxval = 1)

Given a color image, compute the histogram of the red channel.

img = testimage("mandrill")
r = red.(img)
edges, counts  = build_histogram(r, 256, minval = 0, maxval = 1)

References

[1] E. Herrholz, "Parsimonious Histograms," Ph.D. dissertation, Inst. of Math. and Comp. Sci., University of Greifswald, Greifswald, Germany, 2011.

source

Algorithms

ImageContrastAdjustment.HistogramAdjustmentAPI.AbstractHistogramAdjustmentAlgorithmType
AbstractHistogramAdjustmentAlgorithm <: AbstractImageFilter

The root type for ImageContrastAdjustment package.

Any concrete histogram adjustment algorithm shall subtype it to support adjust_histogram and adjust_histogram! APIs.

Examples

All histogram adjustment algorithms in ImageContrastAdjustment are called in the following pattern:

# first generate an algorithm instance
f = LinearStretching()

# then pass the algorithm to `adjust_histogram`
img_adjusted = adjust_histogram(img, f)

# or use in-place version `adjust_histogram!`
img_adjusted = similar(img)
adjust_histogram!(img_adjusted, img, f)

Some algorithms also receive additional information as an argument, e.g., nbins of Equalization.

# you can explicit specify the parameters
f = Equalization(nbins = 32)

For more examples, please check adjust_histogram, adjust_histogram! and concrete algorithms.

source

AdaptiveEqualization

ImageContrastAdjustment.AdaptiveEqualizationType
    AdaptiveEqualization <: AbstractHistogramAdjustmentAlgorithm
    AdaptiveEqualization(; nbins = 256, minval = 0, maxval = 1, rblocks = 8, cblocks = 8, clip = 0.1)

    adjust_histogram([T,] img, f::AdaptiveEqualization)
    adjust_histogram!([out,] img, f::AdaptiveEqualization)

Performs Contrast Limited Adaptive Histogram Equalisation (CLAHE) on the input image. It differs from ordinary histogram equalization in the respect that the adaptive method computes several histograms, each corresponding to a distinct section of the image, and uses them to redistribute the lightness values of the image. It is therefore suitable for improving the local contrast and enhancing the definitions of edges in each region of an image.

Details

Histogram equalisation was initially conceived to improve the contrast in a single-channel grayscale image. The method transforms the distribution of the intensities in an image so that they are as uniform as possible [1]. The natural justification for uniformity is that the image has better contrast if the intensity levels of an image span a wide range on the intensity scale. As it turns out, the necessary transformation is a mapping based on the cumulative histogram–-see Equalization for more details.

A natural extension of histogram equalisation is to apply the contrast enhancement locally rather than globally [2]. Conceptually, one can imagine that the process involves partitioning the image into a grid of rectangular regions and applying histogram equalisation based on the local CDF of each contextual region. However, to smooth the transition of the pixels from one contextual region to another, the mapping of a pixel is not necessarily done soley based on the local CDF of its contextual region. Rather, the mapping of a pixel may be interpolated based on the CDF of its contextual region, and the CDFs of the immediate neighbouring regions.

In adaptive histogram equalisation the image $\mathbf{G}$ is partitioned into $P \times Q$ equisized submatrices,

\[\mathbf{G} = \begin{bmatrix} \mathbf{G}_{11} & \mathbf{G}_{12} & \ldots & \mathbf{G}_{1C} \\ \mathbf{G}_{21} & \mathbf{G}_{22} & \ldots & \mathbf{G}_{2C} \\ \vdots & \vdots & \ldots & \vdots \\ \mathbf{G}_{R1} & \mathbf{G}_{R2} & \ldots & \mathbf{G}_{RC} \\ \end{bmatrix}.\]

For each submatrix $\mathbf{G}_{rc}$, one computes a concomitant CDF, which we shall denote by $T_{rc}(G_{i,j})$. In the most general case, we will require four CDFs

\[\begin{aligned} T_1(v) & \triangleq T_{rc}(G_{i,j}) \\ T_2(v) & \triangleq T_{(r+1)c}(G_{i,j}) \\ T_3(v) & \triangleq T_{(r+1)(c+1)}(G_{i,j}) \\ T_4(v) & \triangleq T_{r(c+1)}(G_{i,j}). \end{aligned}\]

In order to determine which particular CDFs will be used in the interpolation step, it is useful to (i) introduce the function

\[\Phi(\mathbf{G}_{rc}) = \left( \phi_{rc}, \phi'_{rc}\right) \triangleq \left(rP - \frac{P}{2}, cQ - \frac{Q}{2} \right),\]

(ii) form the sequences $\left(\phi_{11}, \phi_{21}, \ldots, \phi_{R1} \right)$ and $\left(\phi'_{11}, \phi'_{12}, \ldots, \phi'_{1C} \right)$, and (iii) define

\[\begin{aligned} t & \triangleq \frac{i - \phi_{r1}}{\phi_{(r+1)1} - \phi_{r1} } \\ u & \triangleq \frac{j - \phi'_{1c}}{\phi'_{1(c+1)} - \phi'_{1c} }. \end{aligned}\]

Case I (Interior)

For a pixel $G_{i,j}$ in the range

\[P - \frac{P}{2} \le i \le RP - \frac{P}{2} \quad \text{and} \quad Q - \frac{Q}{2} \le j \le CQ - \frac{Q}{2}.\]

values of $r$ and $c$ are implicitly defined by the solution to the inequalities

\[\phi_{r1} \le i < \phi_{(r+1)1} \quad \text{and} \quad \phi'_{1c} \le j < \phi'_{1(c+1)}.\]

The bilinearly interpolated transformation that maps an intensity $v$ at location $(i,j)$ in the image to an intensity $v'$ is given by [3]

\[v' \triangleq \bar{T}(v) = (1-t) (1-u)T_1(G_{i,j}) + t(1-u)T_2(G_{i,j}) + tuT_3(G_{i,j}) +(1-t)uT_4(G_{i,j}).\]

Case II (Vertical Border)

For a pixel $G_{i,j}$ in the range

\[P - \frac{P}{2} \le i \le RP - \frac{P}{2} \quad \text{and} \quad 1 \le j < Q - \frac{Q}{2} \; \cup \; CQ - \frac{Q}{2} < j \le CQ,\]

$r$ is implicitly defined by the solution to the inequality $\phi_{r1} \le i < \phi_{(r+1)1}$, while

\[c = \begin{cases} 1, & \text{if } \quad 1 \le j < Q - \frac{Q}{2} \\ C, & \text{if } \quad CQ - \frac{Q}{2} < j \le CQ. \end{cases}\]

The linearly interpolated transformation that maps an intensity $v$ at location $(i,j)$ in the image to an intensity $v'$ is given by

\[v' \triangleq \bar{T}(v) = (1-t)T_1(G_{i,j}) + tT_2(G_{i,j}).\]

Case III (Horizontal Border)

For a pixel $G_{i,j}$ in the range

\[1 \le i < P - \frac{P}{2} \;\cup \; RP - \frac{P}{2} < i \le RP \quad \text{and} \quad Q - \frac{Q}{2} \le j \le CQ - \frac{Q}{2},\]

$c$ is implicitly defined by the solution to the inequality $\phi'_{1c} \le j < \phi'_{1(c+1)}$, while

\[r = \begin{cases} 1, & \text{if } \quad 1 \le i < P - \frac{P}{2} \\ R, & \text{if } \quad RP - \frac{P}{2} < i \le RP . \end{cases}\]

The linearly interpolated transformation that maps an intensity $v$ at location $(i,j)$ in the image to an intensity $v'$ is given by

\[v' \triangleq \bar{T}(v) = (1-u)T_1(G_{i,j}) + uT_4(G_{i,j}).\]

Case IV (Corners)

For a pixel $G_{i,j}$ in the range

\[1 \le i < \frac{P}{2} \;\cup \; RP - \frac{P}{2} < i \le RP \quad \text{and} \quad 1 \le j < CQ - \frac{Q}{2} \; \cup \; CQ - \frac{Q}{2} < j \le CQ ,\]

we have

\[r = \begin{cases} 1, & \text{if } \quad 1 \le i < P - \frac{P}{2} \\ R, & \text{if } \quad RP - \frac{P}{2} < i \le RP \end{cases} \quad \text{and} \quad c = \begin{cases} 1, & \text{if } \quad 1 \le j < Q - \frac{Q}{2} \\ C, & \text{if } \quad CQ - \frac{Q}{2} < j \le CQ. \end{cases}\]

The transformation that maps an intensity $v$ at location $(i,j)$ in the image to an intensity $v'$ is given by

\[v' \triangleq \bar{T}(v) = T_1(G_{i,j}).\]

Limiting Contrast

An unfortunate side-effect of contrast enhancement is that it has a tendency to amplify the level of noise in an image, especially when the magnitude of the contrast enhancement is very high. The magnitude of contrast enhancement is associated with the gradient of $T(\cdot)$, because the gradient determines the extent to which consecutive input intensities are stretched across the grey-level spectrum. One can diminish the level of noise amplification by limiting the magnitude of the contrast enhancement, that is, by limiting the magnitude of the gradient.

Since the derivative of $T(\cdot)$ is the empirical density $\hat{f}_{G}$, the slope of the mapping function at any input intensity is proportional to the height of the histogram $\hat{f}_{G}$ at that intensity. Therefore, limiting the slope of the local mapping function is equivalent to clipping the height of the histogram. A detailed description of the implementation details of the clipping process can be found in [2].

Options

Various options for the parameters of this function are described in more detail below.

Choices for img

The function can handle a variety of input types. The returned image depends on the input type.

For coloured images, the input is converted to YIQ type and the Y channel is equalised. This is the combined with the I and Q channels and the resulting image converted to the same type as the input.

Choices for nbins in AdaptiveEqualization

You can specify the total number of bins in the histogram of each local region.

Choices for rblocks and cblocks in AdaptiveEqualization

The rblocks and cblocks specify the number of blocks to divide the input image into in each direction. By default both values are set to eight.

Choices for clip in AdaptiveEqualization

The clip parameter must be a value between 0 and 1. It defines an implicit threshold at which a histogram is clipped. Counts that exceed the threshold are redistributed as equally as possible so that no bin exceeds the threshold limit. A value of zero means no clipping, whereas a value of one sets the threshold at the smallest feasible bin limit. A bin limit is feasible if all bin counts can be redistributed such that no bin count exceeds the limit. In practice, a clip value of zero corresponds to maximal contrast enhancement, whereas a clip value of one corredponds to minimal contrast enhancement. The default value is 0.1.

Choices for minval and maxval in AdaptiveEqualization

If minval and maxval are specified then intensities are equalized to the range [minval, maxval]. The default values are 0 and 1.

Example


using TestImages, FileIO, ImageView

img =  testimage("mandril_gray")
imgeq = adjust_histogram(img, AdaptiveEqualization(nbins = 256, rblocks = 4, cblocks = 4, clip = 0.2))

imshow(img)
imshow(imgeq)

References

  1. R. C. Gonzalez and R. E. Woods. Digital Image Processing (3rd Edition). Upper Saddle River, NJ, USA: Prentice-Hall, 2006.
  2. S. M. Pizer, E. P. Amburn, J. D. Austin, R. Cromartie, A. Geselowitz, T. Greer, B. ter Haar Romeny, J. B. Zimmerman and K. Zuiderveld “Adaptive histogram equalization and its variations,” Computer Vision, Graphics, and Image Processing, vol. 38, no. 1, p. 99, Apr. 1987. 10.1016/S0734-189X(87)80186-X
  3. W. H. Press, S. A. Teukolsky, W. T. Vetterling, and B. P. Flannery. Numerical Recipes: The Art of Scientific Computing (3rd Edition). New York, NY, USA: Cambridge University Press, 2007.
source

ContrastStretching

ImageContrastAdjustment.ContrastStretchingType
    ContrastStretching <: AbstractHistogramAdjustmentAlgorithm
    ContrastStretching(; t = 0.5,  slope = 1.0)

    adjust_histogram([T,] img, f::ContrastStretching)
    adjust_histogram!([out,] img, f::ContrastStretching)

Returns an image where intensities below t are compressed into a narrower range of dark intensities, and values above t are compressed into a narrower band of light intensities.

Details

Contrast stretching is a transformation that enhances or reduces (for slope > 1 or < 1, respectively) the contrast near saturation (0 and 1). It is given by the relation

\[f(x) = \frac{1}{1 + \left(\frac{t}{x} \right)^s}, \; s \in \mathbb{R},\]

where $s$ represents the slope argument.

Options

Various options for the parameters of the adjust_histogram and ContrastStretching type are described in more detail below.

Choices for img

The function can handle a variety of input types. The returned image depends on the input type.

For colored images, the input is converted to the YIQ type and the intensities of the Y channel are stretched to the specified range. The modified Y channel is then combined with the I and Q channels and the resulting image converted to the same type as the input.

Choice for t

The value of t needs to be in the unit interval. If left unspecified a default value of 0.5 is utilized.

Choice for slope

The value of slope can be any real number. If left unspecified a default value of 1.0 is utilized.

Example

using ImageContrastAdjustment, ImageView, TestImages

img = testimage("mandril_gray")
ret = adjust_histogram(img, ContrastStretching(t = 0.6, slope = 3))

References

  1. Gonzalez, R. C., Woods, R. E., & Eddins, S. L. (2004). Digital image processing using MATLAB (Vol. 624). Upper Saddle River, New Jersey: Pearson-Prentice-Hall.
source

Equalization

ImageContrastAdjustment.EqualizationType
    Equalization <: AbstractHistogramAdjustmentAlgorithm
    Equalization(; nbins = 256, minval = 0, maxval = 1)

    adjust_histogram([T,] img, f::Equalization)
    adjust_histogram!([out,] img, f::Equalization)

Returns a histogram equalized image with a granularity of nbins number of bins.

Details

Histogram equalization was initially conceived to improve the contrast in a single-channel grayscale image. The method transforms the distribution of the intensities in an image so that they are as uniform as possible [1]. The natural justification for uniformity is that the image has better contrast if the intensity levels of an image span a wide range on the intensity scale. As it turns out, the necessary transformation is a mapping based on the cumulative histogram.

One can consider an $L$-bit single-channel $I \times J$ image with gray values in the set $\{0,1,\ldots,L-1 \}$, as a collection of independent and identically distributed random variables. Specifically, let the sample space $\Omega$ be the set of all $IJ$-tuples $\omega =(\omega_{11},\omega_{12},\ldots,\omega_{1J},\omega_{21},\omega_{22},\ldots,\omega_{2J},\omega_{I1},\omega_{I2},\ldots,\omega_{IJ})$, where each $\omega_{ij} \in \{0,1,\ldots, L-1 \}$. Furthermore, impose a probability measure on $\Omega$ such that the functions $\Omega \ni \omega \to \omega_{ij} \in \{0,1,\ldots,L-1\}$ are independent and identically distributed.

One can then regard an image as a matrix of random variables $\mathbf{G} = [G_{i,j}(\omega)]$, where each function $G_{i,j}: \Omega \to \mathbb{R}$ is defined by

\[G_{i,j}(\omega) = \frac{\omega_{ij}}{L-1},\]

and each $G_{i,j}$ is distributed according to some unknown density $f_{G}$. While $f_{G}$ is unknown, one can approximate it with a normalized histogram of gray levels,

\[\hat{f}_{G}(v)= \frac{n_v}{IJ},\]

where

\[n_v = \left | \left\{(i,j)\, |\, G_{i,j}(\omega) = v \right \} \right |\]

represents the number of times a gray level with intensity $v$ occurs in $\mathbf{G}$. To transform the distribution of the intensities so that they are as uniform as possible one needs to find a mapping $T(\cdot)$ such that $T(G_{i,j}) \thicksim U$. The required mapping turns out to be the cumulative distribution function (CDF) of the empirical density $\hat{f}_{G}$,

\[ T(G_{i,j}) = \int_0^{G_{i,j}}\hat{f}_{G}(w)\mathrm{d} w.\]

Options

Various options for the parameters of the adjust_histogram function and Equalization type are described in more detail below.

Choices for img

The adjust_histogram function can handle a variety of input types. By default type of the returned image matches the input type.

For colored images, the input is converted to YIQ type and the Y channel is equalized. This is the combined with the I and Q channels and the resulting image converted to the same type as the input.

Choices for nbins in Equalization

You can specify the total number of bins in the histogram.

Choices for minval and maxval in Equalization

If minval and maxval are specified then intensities are equalized to the range [minval, maxval]. The default values are 0 and 1.

Example


using TestImages, FileIO, ImageView

img =  testimage("mandril_gray")
imgeq = adjust_histogram(img, Equalization(nbins = 256, minval = 0, maxval = 1))

imshow(img)
imshow(imgeq)

References

  1. R. C. Gonzalez and R. E. Woods. Digital Image Processing (3rd Edition). Upper Saddle River, NJ, USA: Prentice-Hall, 2006.
source

LinearStretching

ImageContrastAdjustment.LinearStretchingType
    LinearStretching <: AbstractHistogramAdjustmentAlgorithm
    LinearStretching(; [src_minval], [src_maxval],
                       dst_minval=0, dst_maxval=1,
                       no_clamp=false)

    LinearStretching((src_minval, src_maxval) => (dst_minval, dst_maxval))
    LinearStretching((src_minval, src_maxval) => nothing)
    LinearStretching(nothing => (dst_minval, dst_maxval))

    adjust_histogram([T,] img, f::LinearStretching)
    adjust_histogram!([out,] img, f::LinearStretching)

Returns an image where the range of the intensities spans the interval [dst_minval, dst_maxval].

Details

Linear stretching (also called normalization) is a contrast enhancing transformation that is used to modify the dynamic range of the image. In particular, suppose that the input image has gray values in the range [A,B] and one wishes to change the dynamic range to [a,b] using a linear mapping, then the necessary transformation is given by the relation

\[f(x) = (x-A) \frac{b-a}{B-A} + a.\]

Options

Various options for the parameters of the adjust_histogram and LinearStretching type are described in more detail below.

Choices for img

The function can handle a variety of input types. The returned image depends on the input type.

For colored images, the input is converted to the YIQ type and the intensities of the Y channel are stretched to the specified range. The modified Y channel is then combined with the I and Q channels and the resulting image converted to the same type as the input.

Choices for dst_minval and dst_maxval

If destination value range dst_minval and dst_maxval are specified then intensities are mapped to the range [dst_minval, dst_maxval]. The default values are 0 and 1.

Choices for src_minval and src_maxval

The source value range src_minval and src_maxval specifies the intensity range of input image. By default, the values are extrema(img) (finite). If custom values are provided, the output intensity value will be clamped to range [dst_minval, dst_maxval] if it exceeds that.

no_clamp

Setting no_clamp=true to disable the automatic clamp even if the output intensity value exceeds the range [dst_minval, dst_maxval]. Note that a clamp is still applied for types that has limited value range, for example, if the input eltype is N0f8, then the output will be clamped to [0.0N0f8, 1.0N0f8] even if no_clamp==true.

Example

using ImageContrastAdjustment, TestImages

img = testimage("mandril_gray")
# Stretches the contrast in `img` so that it spans the unit interval.
imgo = adjust_histogram(img, LinearStretching(dst_minval = 0, dst_maxval = 1))

For convenience, Constructing a LinearStretching object using Pair is also supported

# these two constructors are equivalent
LinearStretching(src_minval=0.1, src_maxval=0.9, dst_minval=0.05, dst_maxval=0.95)
LinearStretching((0.1, 0.9) => (0.05, 0.95))

# replace the part with `nothing` to use default values, e.g.,
# specify only destination value range
LinearStretching(nothing => (0.05, 0.95))
# specify only source value range and use default destination value range, i.e., (0, 1)
LinearStretching((0.1, 0.9) => nothing)

References

  1. W. Burger and M. J. Burge. Digital Image Processing. Texts in Computer Science, 2016. doi:10.1007/978-1-4471-6684-9
source

Matching

ImageContrastAdjustment.MatchingType
    Matching <: AbstractHistogramAdjustmentAlgorithm
    Matching(targetimg; nbins = 256, edges = nothing)

    adjust_histogram([T,] img, f::Matching)
    adjust_histogram!([out,] img, f::Matching)

Returns a histogram matched image with a granularity of nbins number of bins. The first argument img is the image to be matched, whereas the argument targetimg in Matching() is the image having the desired histogram to be matched to.

Details

The purpose of histogram matching is to transform the intensities in a source image so that the intensities distribute according to the histogram of a specified target image. If one interprets histograms as piecewise-constant models of probability density functions (see build_histogram), then the histogram matching task can be modelled as the problem of transforming one probability distribution into another [1]. It turns out that the solution to this transformation problem involves the cumulative and inverse cumulative distribution functions of the source and target probability density functions.

In particular, let the random variables $x \thicksim p_{x}$ and $z \thicksim p_{z}$ represent an intensity in the source and target image respectively, and let

\[ S(x) = \int_0^{x}p_{x}(w)\mathrm{d} w \quad \text{and} \quad T(z) = \int_0^{z}p_{z}(w)\mathrm{d} w\]

represent their concomitant cumulative distribution functions. Then the sought-after mapping $Q(\cdot)$ such that $Q(x) \thicksim p_{z}$ is given by

\[Q(x) = T^{-1}\left( S(x) \right),\]

where $T^{-1}(y) = \operatorname{min} \{ x \in \mathbb{R} : y \leq T(x) \}$ is the inverse cumulative distribution function of $T(x)$.

The mapping suggests that one can conceptualize histogram matching as performing histogram equalization on the source and target image and relating the two equalized histograms. Refer to adjust_histogram for more details on histogram equalization.

Options

Various options for the parameters of the adjust_histogram function and Matching type are described in more detail below.

Choices for img and targetimg

The adjust_histogram(img, Matching()) function can handle a variety of input types. The type of the returned image matches the input type.

For colored images, the inputs are converted to YIQ type and the distributions of the Y channels are matched. The modified Y channel is then combined with the I and Q channels and the resulting image converted to the same type as the input.

Choices for nbins

You can specify the total number of bins in the histogram. If you do not specify the number of bins then a default value of 256 bins is utilized.

Choices for edges

If you do not designate the number of bins, then you have the option to directly stipulate how the intervals will be divided by specifying a AbstractRange type.

Example

using Images, TestImages, ImageView

img_source = testimage("mandril_gray")
img_target = adjust_histogram(img_source, GammaCorrection(gamma = 0.5))
img_transformed = adjust_histogram(img_source, Matching(targetimg = img_target))
#=
    A visual inspection confirms that img_transformed resembles img_target
    much more closely than img_source.
=#
imshow(img_source)
imshow(img_target)
imshow(img_transformed)

References

  1. W. Burger and M. J. Burge. Digital Image Processing. Texts in Computer Science, 2016. doi:10.1007/978-1-4471-6684-9
source

MidwayEqualization

ImageContrastAdjustment.MidwayEqualizationType
    MidwayEqualization <: AbstractHistogramAdjustmentAlgorithm
    MidwayEqualization(; nbins = 256, minval = 0, maxval = 1)

    adjust_histogram([T,] img_sequence, f::MidwayEqualization(nbins = 256, edges = nothing))
    adjust_histogram!([out_sequence,] img_sequence, f::MidwayEqualization(nbins = 256, edges = nothing))

Gives a pair of images the same histogram whilst maintaining as much as possible their previous grey level dynamics.

Details

The purpose of midway histogram equalization is to transform the intensities in a pair of images so that the intensities distribute according to a common "midway" distribution. The histogram representing the common distribution is chosen so that the original gray level dynamics of the images are preserved as much as possible. If one interprets histograms as piecewise-constant models of probability density functions (see build_histogram), then the midway histogram equalization task can be modeled as the problem of transforming one probability distribution into another (see adjust_histogram). It turns out that the solution to this transformation problem involves the cumulative and inverse cumulative distribution functions of the source and "midway" probability density functions. In particular, let the random variables $X_i \thicksim p_{x_i} \; (i = 1,2)$, and $Z \thicksim p_{z}$ represent an intensity in the first, second and "midway" image respectively, and let

\[ S_{X_i}(x) = \int_0^{x}p_{x_i}(w)\mathrm{d} w \; \quad \text{and} \quad T_{Z}(x) = \frac{2}{\frac{1}{S_{X_1}(x)} + \frac{1}{S_{X_2}(x)}}\]

represent the cumulative distribution functions of the two input images, and their harmonic mean, respectively. Then the sought-after mapping $Q_{X_i}(\cdot)$ $(i = 1,2)$ such that $Q_{X_i}(x) \thicksim p_{z}$ is given by

\[Q_{X_i}(x) = T_{Z}^{-1}\left( S_{X_i}(x) \right),\]

where $T_{Z}^{-1}(y) = \operatorname{min} \{ x \in \mathbb{R} : y \leq T_{Z}(x) \}$ is the inverse cumulative distribution function of $T_{Z}(x)$.

Options

Various options for the parameters of the adjust_histogram function and MidwayEqualization types are described in more detail below.

Choices for img_sequence

The function adjust_histogram expects a length-2 Vector of images (the pair of images) and returns a length-2 Vector of modified images. The function can handle a variety of input types. The type of the returned image matches the input type.

For colored images, the inputs are converted to YIQ type and the distributions of the Y channels are transformed according to a "midway" distribution. The modified Y channel is then combined with the I and Q channels and the resulting image converted to the same type as the input.

Choices for nbins

You can specify the total number of bins in the histogram. If you do not specify the number of bins then a default value of 256 bins is utilized.

Choices for edges

If you do not designate the number of bins, then you have the option to directly stipulate how the intervals will be divided by specifying a AbstractRange type.

Example

using Images, TestImages, ImageView, ImageContrastAdjustment

img = testimage("mandril_gray")

# The same image but with different intensitiy distributions
img1 = adjust_histogram(img, GammaCorrection(gamma = 2))
img2 = adjust_histogram(img, GammaCorrection(gamma = 1.2))

# Midway histogram equalization will transform these two images so that their
# intensity distributions are almost identical.
img_sequence = adjust_histogram([img1, img2], MidwayEqualization(nbins = 256))
img1o = first(img_sequence)
img2o = last(img_sequence)

References

  1. T. Guillemot and J. Delon, “Implementation of the Midway Image Equalization,” Image Processing On Line, vol. 5, pp. 114–129, Jun. 2016. doi:10.5201/ipol.2016.140
source