# Function References

## General function

`ImageContrastAdjustment.HistogramAdjustmentAPI.adjust_histogram`

— Function`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.

`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`

`ImageContrastAdjustment.build_histogram`

— Function```
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

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

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

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

**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.

## Algorithms

`ImageContrastAdjustment.HistogramAdjustmentAPI.AbstractHistogramAdjustmentAlgorithm`

— Type`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.

### AdaptiveEqualization

`ImageContrastAdjustment.AdaptiveEqualization`

— Type```
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,

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

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

(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

**Case I (Interior)**

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

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

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

**Case II (Vertical Border)**

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

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

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

**Case III (Horizontal Border)**

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

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

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

**Case IV (Corners)**

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

we have

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

**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**

- R. C. Gonzalez and R. E. Woods.
*Digital Image Processing (3rd Edition)*. Upper Saddle River, NJ, USA: Prentice-Hall, 2006. - 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 - 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.

### ContrastStretching

`ImageContrastAdjustment.ContrastStretching`

— Type```
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

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**

- 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.

### Equalization

`ImageContrastAdjustment.Equalization`

— Type```
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

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,

where

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}$,

**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**

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

### LinearStretching

`ImageContrastAdjustment.LinearStretching`

— Type```
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

**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**

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

### Matching

`ImageContrastAdjustment.Matching`

— Type```
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

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

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**

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

### MidwayEqualization

`ImageContrastAdjustment.MidwayEqualization`

— Type```
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

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

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**

- 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