I'd like to use the Metropolis algorithm to randomly generate points with density according to the brightness of an image. I just need to transform a binary image into a pdf function to use this answer.
First attempt:
img = ColorNegate@ColorConvert[ImageResize[lena[], 50], "Grayscale"];
dims = ImageDimensions[img];
data = Flatten[
Table[{{i, j}, PixelValue[img, {i, j}]}, {i, dims[[1]]}, {j,
dims[[2]]}], 1];
f = Interpolation[data]
ContourPlot[f[x, y], {x, 1, dims[[1]]}, {y, 1, dims[[2]]}]
Metropolis /:
Random`DistributionVector[
Metropolis[pdf_, u0_, s_: 1, n0_: 100, chains_: 200], n_Integer,
prec_?Positive] :=
Module[{u, du, p, p1, accept, cpdf},
cpdf = Compile @@ {{#, _Real} & /@ #, pdf @@ #,
RuntimeAttributes -> {Listable}, RuntimeOptions -> "Speed"} &[
Unique["x", Temporary] & /@ u0];
u = ConstantArray[u0, chains];
p = cpdf @@ Transpose[u];
(Join @@
Table[du =
RandomVariate[
NormalDistribution[0, s], {chains, Length[u0]}];
p1 = cpdf @@ Transpose[u + du];
accept = UnitStep[p1/p - RandomReal[{0, 1}, chains]];
p += (p1 - p) accept;
u += du accept, {Ceiling[(n0 + n)/chains]}])[[n0 + 1 ;;
n0 + n]]];
p = RandomVariate[Metropolis[f, {25, 25}], 30000];
ListPlot[p, AspectRatio -> Automatic]
HistogramDistribution[]
orSmoothKernelDistribution[]
? Related to this, look up the docs forImageHistogram[]
. $\endgroup$HistogramDistribution
and similar are not what you want. $\endgroup$