({{, (RefLink[HistogramTransform, paclet:ref/HistogramTransform])[image] 
transforms pixel values of image so that its histogram is nearly flat.}, {, (RefLink[HistogramTransform, paclet:ref/HistogramTransform])[image,dist]
modifies pixel values of image so that its histogram matches the probability density function (PDF) of the distribution dist.}, {, (RefLink[HistogramTransform, paclet:ref/HistogramTransform])[image,ref]
matches the histogram of image with the histogram of the reference image ref.}, {, (RefLink[HistogramTransform, paclet:ref/HistogramTransform])[{(Subscript[x, 1]),(Subscript[x, 2]),…},…]
transforms values (Subscript[x, i]).}})

OpenersNotesSection(Spacer1)Details

(RefLink[HistogramTransform, paclet:ref/HistogramTransform])[image] effectively applies the histogram equalization to image.

(RefLink[HistogramTransform, paclet:ref/HistogramTransform]) works with 3D as well as 2D images, and also with lists of arbitrary rank datasets.

(RefLink[HistogramTransform, paclet:ref/HistogramTransform])[image,ref] finds an interpolating function between the quantiles of image and ref and applies it to each pixel in image, effectively known as histogram matching.

(RefLink[HistogramTransform, paclet:ref/HistogramTransform])[image,…] returns an image of the same type as the input image.

With multichannel images, (RefLink[HistogramTransform, paclet:ref/HistogramTransform])[image] operates separately on each channel.

(RefLink[HistogramTransform, paclet:ref/HistogramTransform])[{(Subscript[data, 1]),(Subscript[data, 2]),…},…] transforms multiple datasets (Subscript[data, i]).

In (RefLink[HistogramTransform, paclet:ref/HistogramTransform])[image,ref], ref should be a univariate distribution, an image with either one channel or the same number of channels as image, a list of values, or a list of datasets with length equal to the number of channels in image.

(RefLink[HistogramTransform, paclet:ref/HistogramTransform])[source] is equivalent to (RefLink[HistogramTransform, paclet:ref/HistogramTransform])[source,(RefLink[UniformDistribution, paclet:ref/UniformDistribution])[{0,1}]].

(RefLink[HistogramTransform, paclet:ref/HistogramTransform])[source,ref,n] finds an interpolating function with n equally spaced quantiles.

(RefLink[HistogramTransform, paclet:ref/HistogramTransform])[image,ref] is equivalent to (RefLink[HistogramTransform, paclet:ref/HistogramTransform])[image,ref,256].

With (RefLink[HistogramTransform, paclet:ref/HistogramTransform])[data,ref,(RefLink[Automatic, paclet:ref/Automatic])], the number of quantiles is the same as the number of bins used in (RefLink[Histogram, paclet:ref/Histogram])[data].

OpenersPrimaryExamplesSection(Spacer1)Examples  (15)

OpenersExampleSection0(Spacer1)Basic Examples  (3)

Equalize the histogram of an image:

HistogramTransform[]

Match histograms of two color images:

HistogramTransform[,]

Match the image histogram with a reference image:

HistogramTransform[,]

OpenersExampleSection1(Spacer1)Scope  (6)

Transform a dataset so that it is distributed normally:

data={91,69,16,16,11,24,23,7,83,79,17,22,50,37,36,61,22,34,39,63,59,75,10,81,71,73,77,27,58,1,23,61,19,27,86,36,3,30,68,89,29,57,13,92,7,60,80,53,14,66};
Histogram[data]

HistogramTransform[data,NormalDistribution[60,10]]

Histogram[%]

Transform multiple datasets so that they are distributed uniformly:

datasets=Table[RandomVariate[dist,1000],{dist,{NormalDistribution[],ChiSquareDistribution[4],ExponentialDistribution[1/2]}}];
Histogram[datasets,ChartLayout->"Stacked"]

flat=HistogramTransform[datasets];
Histogram[flat,ChartLayout->"Stacked"]

Make the pixel values follow a normal distribution:

i=;

r=HistogramTransform[i,NormalDistribution[.5,.2]]

Compare the two histograms:

ImageHistogram[#,32,ImageSize->200]&/@{i,r}

Reshape the image histogram so that each channel follows a normal distribution:

HistogramTransform[,NormalDistribution[.5,.2]]

Reducing the number of quantiles will affect the quality of the transformation function:

img=;
res=HistogramTransform[img,NormalDistribution[.5,.1],#]&/@{4,8,64};
Grid[{res,ImageHistogram[#,50]&/@res}]

Equalize the histogram of a 3D image:

HistogramTransform[]

OpenersExampleSection3(Spacer1)Applications  (6)

OpenersExampleSubsection0(Spacer1)Basic Applications  (3)

Equalize only the brightness of a color image:

{h,s,b}=ColorSeparate[,"HSB"];
ColorCombine[{h,s,HistogramTransform[b]},"HSB"]

Equalize only the saturation of a color image:

{h,s,b}=ColorSeparate[,"HSB"];
ColorCombine[{h,HistogramTransform[s],b},"HSB"]

Create an image effect by composing an image and its equalized version:

img=;
ImageCompose[img,{HistogramTransform[img],.5}]

OpenersExampleSubsection1(Spacer1)Color Transformation  (2)

Transfer colors between images:

img=;ref=;
HistogramTransform[img,ref]

Perform the transfer in the Lab color space instead:

HistogramTransform[ColorConvert[img,"LAB"],ColorConvert[ref,"LAB"]]

Colorize a grayscale image by searching for neighborhoods with similar luminance in a color image:

img=;ref=;

Convert images into a color space where luminance and color information are not correlated:

limg=First@ColorSeparate[img,"LAB"];
{lref,aref,bref}=ColorSeparate[ref,"LAB"];

Normalize the luminance images by reshaping the histogram:

l2=HistogramTransform[limg,lref];
ImageHistogram/@{l2,lref}

Compute luminance neighborhood statistics and construct a function that gives the color associated to the closest luminance neighborhood:

radius=2;
{neighimg,neighref}=ColorCombine[{
MeanFilter[#,radius],
StandardDeviationFilter[#,radius]}]&/@{l2,lref};
nfun=Nearest[Flatten[ImageData@neighref,1]->Transpose[Flatten@ImageData@#&/@{aref,bref}]];

For each pixel of the grayscale image, create a new pixel by preserving the initial luminance and selecting the nearest color in the reference image:

col=Map[First@nfun[#,1]&,ImageData@neighimg,{2}];
ColorConvert[Image[Join[{ImageData@limg},Transpose[col,{2,3,1}]],Interleaving->False,ColorSpace->"LAB"],"RGB"]

OpenersExampleSubsection2(Spacer1)Multidimensional Probability Density Function Transfer  (1)

Reshape the histogram of a multidimensional dataset by iteratively reshaping random marginal histograms:

multidimensionalReshape[source_,ref_,ϵ_:10^-10,maxiterations_:200]:=
FixedPoint[
With[{R=randomRotationMatrix[Length[source]]},
Transpose[R].HistogramTransform[R.#,R.ref]]&,
source,maxiterations,SameTest->(RootMeanSquare[Norm/@Transpose[#1-#2]]<ϵ&)];
randomRotationMatrix[n_]:=If[Det@#==1,#,randomRotationMatrix[n]]&[Transpose@#.DiagonalMatrix[Sign@Diagonal@#2]&@@QRDecomposition@RandomReal[NormalDistribution[],{n,n}]];

Reshape a bivariate dataset to match binormal samples:

dist1=DirichletDistribution[{1,3,2}];
dist2=MultinormalDistribution[{-1,1},{{1,1},{1,4}}];

SeedRandom[0];
transformed=Transpose@multidimensionalReshape[
Transpose[x=RandomVariate[dist1,1000]],Transpose@RandomVariate[dist2,1000]];

Assess the result by visualizing the joint histograms before and after the transfer, and by testing whether the transformed data is distributed according to the reference distribution:

Histogram3D[#,Automatic,"PDF"]&/@{x,transformed}

DistributionFitTest[transformed,dist2]

Reshape the joint histogram of the hue and the saturation to a circle:

{h,s,b}=ColorSeparate[,"HSB"];
source=Flatten[ImageData[#]]&/@{h,s};
With[{a=Range[0,2π,2π/10000.]},
ref=1/2+1/2*{Cos[a],Sin[a]}];

SeedRandom[0];
newhs=multidimensionalReshape[source,ref,10^-3];

Visualize the joint histograms before and after the transfer:

Histogram3D[Transpose@#,Automatic,"PDF"]&/@{source,newhs}

Create the corresponding result image:

Image[Append[Partition[#,First@ImageDimensions@b]&/@newhs,ImageData@b],Interleaving->False,ColorSpace->"HSB"]

Reshape the 3D joint histogram of an RGB image:

SeedRandom[0];
new=multidimensionalReshape[Flatten/@ImageData[img=,Interleaving->False],Flatten/@ImageData[,Interleaving->False],10^-3,5];
Image[Partition[#,First@ImageDimensions@img]&/@new,Interleaving->False]

({{DocumentationFooterIconsRelatedFunction.png, ({{See Also}, {(RefLink[Histogram, paclet:ref/Histogram])  ▪  (RefLink[BinCounts, paclet:ref/BinCounts])  ▪  (RefLink[ImageHistogram, paclet:ref/ImageHistogram])  ▪  (RefLink[ImageLevels, paclet:ref/ImageLevels])  ▪  (RefLink[ColorToneMapping, paclet:ref/ColorToneMapping])  ▪  (RefLink[ImageAdjust, paclet:ref/ImageAdjust])  ▪  (RefLink[ColorBalance, paclet:ref/ColorBalance])  ▪  (RefLink[HistogramTransformInterpolation, paclet:ref/HistogramTransformInterpolation])  ▪  (RefLink[Quantile, paclet:ref/Quantile])  ▪  (RefLink[PDF, paclet:ref/PDF])  ▪  (RefLink[UniformDistribution, paclet:ref/UniformDistribution])  ▪  (RefLink[HistogramDistribution, paclet:ref/HistogramDistribution])  ▪  (RefLink[TransformedDistribution, paclet:ref/TransformedDistribution])  ▪  (RefLink[ImageRestyle, paclet:ref/ImageRestyle])}})}})

({{DocumentationFooterIconsRelatedGuide.png, ({{Related Guides}, {▪(RefLinkPlain[Image Restoration, paclet:guide/ImageRestoration])}, {▪(RefLinkPlain[Color Processing, paclet:guide/ColorProcessing])}, {▪(RefLinkPlain[Image Processing & Analysis, paclet:guide/ImageProcessing])}, {▪(RefLinkPlain[Computational Photography, paclet:guide/ComputationalPhotography])}, {▪(RefLinkPlain[Image Computation for Microscopy, paclet:guide/ImageComputationForMicroscopy])}})}})