MeanShift
Details and Options
- MeanShift is also known as mode seeking and is typically used to smooth data arrays and images.
- MeanShift preserves the ordering of the input elements.
- In MeanShift[image,d,parts], parts can be a marker image or a list of {row,column} positions.
- The following options can be given:
-
DistanceFunction EuclideanDistance distance metric function MaxIterations 1 maximum number of iterations to perform Tolerance 0 allowed tolerance to assume convergence Weights Automatic weights to use for computing the mean - With Tolerance->t, mean-shift iterations stop if no point changes by more than t.
- By default, unit weights are used. Using Weights->f, function f applied to rescaled distances between elements is used to compute and return a weighted mean of the values. Distances between 0 and d are rescaled to be in the range from 0 and 1.
- Typical settings for Weights include:
-
UnitStep unit weights (default) UnitTriangle linearly decreasing weight "Gaussian" weights based on a Gaussian window with sigma 
{"Gaussian",σ} Gaussian window with sigma σ - Common settings for the DistanceFunction option are:
-
ManhattanDistance Manhattan or "city block" distance EuclideanDistance Euclidean distance SquaredEuclideanDistance squared Euclidean distance NormalizedSquaredEuclideanDistance normalized squared Euclidean distance CosineDistance angular cosine distance CorrelationDistance correlation coefficient distance f use an arbitrary function f
Examples
open all close allBasic Examples (3)
Mean shift of a list of integers:
MeanShift[{0, 10, 1, 11}, 1]Mean shift of a list of vectors:
MeanShift[{{0, 1}, {2, 3}, {10 , 11}, {12, 13}}, 3]Mean shift of an image's pixels after multiple iterations:
MeanShift[[image], .15, MaxIterations -> 15]Scope (4)
Remove uniform noise from a dataset:
data = Table[1 + RandomReal[{-0.1, 0.1}], {10}]MeanShift[data, 0.1, MaxIterations -> 10]Mean-shift algorithm applied to symbolic expressions:
MeanShift[{1, 2, a + 5, a + 6}, 1]Mean-shift algorithm applied to a subset of the points:
MeanShift[{10, 20, 30, 45, 50}, 10, {1, 3}]Precision of the input is preserved:
MeanShift[{1.0000000000000000000, 2.0000000000000000000, 3.0000000000000000000, 4.0000000000000000000}, 2]Options (8)
DistanceFunction (3)
By default, EuclideanDistance is used:
MeanShift[{0, 1, 10, 11}, 2]MeanShift[{{0, 0}, {1, 1}, {0, 10}, {0, 11}}, 1]Specify the distance function:
MeanShift[{{0, 0}, {1, 1}, {0, 10}, {0, 11}}, 1, DistanceFunction -> ChessboardDistance]Use a custom distance function:
MeanShift[{{0, 0}, {1, 1}, {0, 10}, {0, 11}}, 1, DistanceFunction -> (Min[#1 - #2]&)]MaxIterations (2)
By default, only one iteration of mean shift is applied to input:
MeanShift[{1, 2, 3, 4, 5}, 1]Use MaxIterations to specify the number of iterations:
MeanShift[{1, 2, 3, 4, 5}, 1, MaxIterations -> 5]Use MaxIterations->Infinity to run until convergence:
MeanShift[{1, 2, 3, 4, 5}, 1, MaxIterations -> Infinity]Use MaxIterations to iteratively smooth data:
BlockRandom[SeedRandom[0];
data = Table[1. + RandomReal[{-0.1, 0.1}], {1000}]];
{Table[ListLinePlot[{data, MeanShift[data, 0.05, MaxIterations -> iter]}],
{iter, {1, 5, 10}}]}//GridTolerance (1)
Weights (2)
By default, uniform weights are used:
MeanShift[{0, 1, 3}, 2]Weigh neighbors linearly, based on their distance from each sample:
MeanShift[{0, 1, 3}, 2, Weights -> UnitTriangle]Weigh neighbors exponentially, based on their squared distance from each sample:
MeanShift[{0, 1, 3}, 2, Weights -> {"Gaussian", 1 / 2}]By "Gaussian" weights for color segmentation:
i = [image];MeanShift[i, .3, MaxIterations -> Infinity, Weights -> "Gaussian"]MeanShift[i, .3, MaxIterations -> Infinity]Applications (9)
Smoothing (2)
Find large-scale features in a noisy dataset:
data = ({Sin[#], Cos[#]} + RandomReal[{-0.1, 0.1}, 2])& /@ RandomReal[{0, 2 Pi}, 2000];ListPlot[data]ListPlot[MeanShift[data, 0.1, MaxIterations -> 3]]Image smoothing using mean shift of 5D features in the joint spatial-range domain:
img = [image];
{w, h} = ImageDimensions[img];Use LABColor values, suitable for computing color distances:
pix = Flatten[ImageData[ColorConvert[img, "LAB"]], 1];Compute spatial location features normalized to the range 0 to 1:
pos = Flatten[N@Array[{#1, #2}&, {h, w}], 1];Construct 5D features from color and location of pixels:
data = Join[pix, pos / Max[{h, w}], 2];Perform one iteration of mean-shift filtering using "Gaussian" weights and EuclideanDistance, which is equivalent to multiplying Gaussian-weighted spatial and range features:
ms = MeanShift[data, 0.1, Weights -> "Gaussian"];Create the output image using the filtered color values:
Image[ArrayReshape[ms[[All, ;; 3]], {h, w, 3}], ColorSpace -> "LAB"]AbsoluteTiming[ms = MeanShift[data, 0.1, Weights -> "Gaussian", MaxIterations -> 10];]Image[ArrayReshape[ms[[All, ;; 3]], {h, w, 3}], ColorSpace -> "LAB"]Mean-Shift Displacement (2)
Compute a 1D mean-shift vector:
list = {1, 2, 3, 4};
ms = MeanShift[list, 1]msvector = ms - listBlockRandom[
SeedRandom[0];
list = Join[RandomVariate[BinormalDistribution[{0, 0}, {1, 1 / 2}, 0], 2000], {{2., -1.}}]];Histogram3D[list]Compute the trajectory of a point as it iteratively ascends toward the mode:
index = {Length[list]};
radius = 1 / 2;
pos = Flatten[
FixedPointList[
Part[MeanShift[ReplacePart[list, Thread[index -> #]], radius, index], index]&,
Part[list, index], SameTest -> (Max@Abs[#1 - #2] < 10 ^ -10&)
], 1];Visualize the norm and direction of the successive mean-shift vectors:
msvectors = Differences[pos];ListLinePlot[Norm /@ msvectors, PlotRange -> All, Filling -> Axis, FillingStyle -> Automatic, ColorFunctionScaling -> False, ColorFunction -> Function[{x, y}, Hue[Rescale[ArcTan[Sequence@@msvectors[[x]]], {-Pi, Pi}]]]]pdf = Function[{x, y}, Evaluate[PDF[SmoothKernelDistribution[list], {x, y}]]];
point3D[{x_, y_}] := Point[{x, y, pdf[x, y] + .005}];Show[Plot3D[pdf[x, y], {x, -4, 4}, {y, -2, 2}, PlotRange -> All, ImageSize -> 300], Graphics3D[{Red, PointSize[Medium], point3D /@ pos}]]Find Modes of Estimated Distribution (1)
Get sample data from some distribution with three modes: 0, 2, and 4:
dist = MixtureDistribution[{1, 1, 2}, {NormalDistribution[0, 1 / 4], NormalDistribution[2, 1 / 3], NormalDistribution[4, 1 / 2]}];n = 10000;
BlockRandom[SeedRandom[0];data = RandomVariate[dist, n]];Show[Histogram[data, Automatic, "PDF", PlotRange -> {{-1, 6}, {0, .5}}], Plot[PDF[dist, x], {x, -1, 6}]]Apply mean shift until convergence for samples that tessellates the data:
idx = Flatten[Position[data, #, 1, 1]& /@ Quantile[data, Range[1, n, n / 100] / n]];radius = 0.25;
ms = Part[MeanShift[data, radius, idx, MaxIterations -> ∞, Weights -> "Gaussian", Tolerance -> 10 ^ -10], idx];Prune points that are not local maxima of the underlying PDF by restarting mean shift from a perturbed position:
perturbed = ReplacePart[data, Thread[idx -> ms + radius * RandomChoice[{-1, 1}, Length[idx]]]];msperturb = Part[MeanShift[perturbed, radius, idx, MaxIterations -> ∞, Weights -> "Gaussian", Tolerance -> 10 ^ -10], idx];peaks = Extract[ms, Position[ms - msperturb, x_ /; Abs[x] < 10 ^ -2]]Find modes by gathering the nearby peaks:
modes = Mean /@ Gather[peaks, Abs[#1 - #2] ≤ radius&]Show[Histogram[data, Automatic, "PDF", PlotRange -> {{-1, 6}, {0, .5}}], Plot[PDF[dist, x], {x, -1, 6}], Epilog -> {Red, Line[{{#, 0}, {#, 1}}]& /@ modes}]Clustering (2)
Generate data from some distribution:
list = Join[
({Cos[#], Sin[#]} + RandomReal[{-0.1, 0.1}, 2])& /@ RandomVariate[NormalDistribution[Pi, 1], 1000],
RandomVariate[BinormalDistribution[{1, -1}, {.3, .5}, 0], 1000],
RandomVariate[BinormalDistribution[{1, 1}, {.3, .5}, 0], 1000]
];ListPlot[list]Apply mean shift until all data points have converged:
res = MeanShift[list, .4, MaxIterations -> ∞, DistanceFunction -> SquaredEuclideanDistance, Weights -> UnitTriangle, Tolerance -> 10 ^ -10];Gather the result into clusters:
c = ArrayComponents[res, 1];
clust = GatherBy[Transpose[{list, c}], Last];
clust = #[[All, 1]]& /@ clust;ListPlot[clust]Generate a large amount of data from some distribution:
n = 10000;
dist = MixtureDistribution[{1, 1}, {BinormalDistribution[{-3 / 2, 0}, {1, 1}, 0], BinormalDistribution[{3 / 2, 0}, {1, 1}, 0]}];
BlockRandom[SeedRandom[1];data = RandomVariate[dist, n]];{ListPlot[data], Plot3D[PDF[dist, {x, y}], {x, -6, 6}, {y, -4, 4}, PlotRange -> All]}Compute trajectories for a fraction of the data samples:
indices = RandomSample[Range[n], 100];
radius = .2;paths = Transpose@FixedPointList[
Part[MeanShift[ReplacePart[data, Thread[indices -> #]], 1, indices, Weights -> "Gaussian"], indices]&,
Part[data, indices],
∞, SameTest -> (Max@Abs[#1 - #2] < 10 ^ -10&)];ListLinePlot[paths, PlotRange -> {{-4, 4}, {-3, 3}}]Merge paths that end within radius of each other:
groups = Gather[Range[Length@indices], EuclideanDistance[paths[[#1, -1]], paths[[#2, -1]]] ≤ radius&];Label each trajectory and compute the corresponding nearest function:
l = Table[Position[groups, i, 2][[1, 1]], {i, Length[indices]}];
Short[l]labels = ConstantArray[0, n];
labels[[indices]] = l;nf = Nearest[Flatten[Table[# -> l[[i]]& /@ paths[[i]], {i, Length[indices]}]]];Each unlabeled sample is assigned the label of the closest trajectory:
Table[
labels[[i]] = First@nf[data[[i]]],
{i, Complement[Range[n], indices]}];clust = GatherBy[Transpose[{data, labels}], Last];
clust = #[[All, 1]]& /@ clust;
ListPlot[clust]Computing the mean shift until convergence for the entire dataset would take much longer:
AbsoluteTiming[res = MeanShift[data, 1, MaxIterations -> ∞, Weights -> "Gaussian", Tolerance -> 10 ^ -10];]Image Segmentation (2)
Iterate mean-shift filtering in the 3D feature space of the "LAB" color components:
img = [image];radius = 0.15;
ms = MeanShift[ColorConvert[img, "LAB"], radius, MaxIterations -> 10]Perform mean-shift filtering in the 5D spatial-range feature domain:
img = [image];
{w, h} = ImageDimensions[img];pix = Flatten[ImageData[ColorConvert[img, "LAB"]], 1];
pos = Flatten[N@Array[{#1, #2} / Max[{h, w}]&, {h, w}], 1];
data = Join[pix, pos, 2];radius = 0.25;
AbsoluteTiming[ms = MeanShift[data, radius, Weights -> "Gaussian", MaxIterations -> 10];]Merge components whose feature values are apart by less than the radius:
comp = SortBy[Tally[ms], -Last[#]&];
groups = SortBy[#, Function[c, -Last[c]]]& /@ Gather[comp, EuclideanDistance[First[#1], First[#2]] ≤ radius&];
Length[groups]d = ms;
rules = Table[
Map[#[[1]] -> g[[1, 1]]&, Rest[g]],
{g, Cases[groups, x_ /; Length[x] > 1]}];
d = d /. Dispatch[Flatten[rules]];Compute the final segments and quantized image:
segments = ArrayReshape[ArrayComponents[d, 1], {h, w}];
resimg = Image[ArrayReshape[d[[All, ;; 3]], {h, w, 3}], ColorSpace -> "LAB"];Image[#, ImageSize -> 200]& /@ {Colorize[segments], resimg}Properties & Relations (3)
Perform mean shift on some parts of a list:
list = {10, 20, 30, 40, 55};
parts = {4, 1};
ms = MeanShift[list, 10, parts]Extract the mean-shifted elements:
Part[ms, parts]Perform mean shift on some parts of an image:
i = [image];Create a mask for the first detected bright component:
mask = SelectComponents[Binarize[i], #Label == 1&]ms = MeanShift[i, .15, mask, MaxIterations -> 10]Extract the mean-shifted pixel values:
PixelValue[ms, PixelValuePositions[mask, 1]]//ShallowThe mean-shift vector is proportional to the gradient density estimate normalized by the density estimate:
dist = BinormalDistribution[{0, 0}, {1, 2}, 0];
radius = 1;BlockRandom[
SeedRandom[1];
data = RandomVariate[dist, 10 ^ 4]
];msvector = MeanShift[data, radius] - data;pdf = Function[{x, y}, Evaluate[PDF[dist, {x, y}]]];
grad = Function[{x, y}, Evaluate[{D[pdf[x, y], x], D[pdf[x, y], y]}]];δ = MapThread[CosineDistance[#1, grad[Sequence@@#2] / pdf[Sequence@@#2]]&, {msvector, data}];{Min[δ], Median[δ], Max[δ]}See Also
Related Guides
Text
Wolfram Research (2010), MeanShift, Wolfram Language function, https://reference.wolfram.com/language/ref/MeanShift.html (updated 2014).
CMS
Wolfram Language. 2010. "MeanShift." Wolfram Language & System Documentation Center. Wolfram Research. Last Modified 2014. https://reference.wolfram.com/language/ref/MeanShift.html.
APA
Wolfram Language. (2010). MeanShift. Wolfram Language & System Documentation Center. Retrieved from https://reference.wolfram.com/language/ref/MeanShift.html
BibTeX
@misc{reference.wolfram_2026_meanshift, author="Wolfram Research", title="{MeanShift}", year="2014", howpublished="\url{https://reference.wolfram.com/language/ref/MeanShift.html}", note=[Accessed: 12-June-2026]}
BibLaTeX
@online{reference.wolfram_2026_meanshift, organization={Wolfram Research}, title={MeanShift}, year={2014}, url={https://reference.wolfram.com/language/ref/MeanShift.html}, note=[Accessed: 12-June-2026]}