Generating uniform random points over a binary image

Update

Silvia proposed a much faster algorithm that I believe produces I uniform distribution.
Here is my implementation of it.

pointsInMask2[mask_Image, n_Integer, range : {_, _} : {0, 1/2}] :=
  Reverse @ ImageData @ Binarize[mask, range]\[Transpose] //
    SparseArray[#]["NonzeroPositions"] & //
      RandomChoice[#, n] + RandomReal[{-1, 0}, {n, 2}] &

img = Import["http://i.stack.imgur.com/yoPNX.png"];

Graphics[{
  AbsolutePointSize[1], Opacity[0.3],
  pointsInMask2[img, 75000] // Point
}]

enter image description here

The optional range parameter specifies the range of values in the mask image that are valid target area.

Graphics[{
  AbsolutePointSize[1], Opacity[0.3],
  pointsInMask2[img, 75000, {1/2, 1}] // Point
}]

enter image description here


A "brute force" method

Although my first method will be superior if one wishes to generate many points there is a more direct and simple approach, though it does not benefit from any of the optimizations in the linked question. That is simply to generate random points and select the ones for which the matching ImageValue is closer to black than white. This requires redundant sampling and will be increasingly slow on images with a small percentage of black pixels. (For now I am simply estimating the number of samples needed and not performing a check to make sure the requested number are actually produced; if this method proves useful I shall refine my approach.)

pointsInMask[mask_Image, n_Integer] :=
  Module[{dims, pts, n2},
    dims = ImageDimensions[mask];
    n2 = ⌈ 1.1 n #/(# - ImageData[mask] ~Total~ 2) &[Times @@ dims] ⌉;
    pts = RandomReal[#, n2] & /@ dims // Transpose;
    Select[pts, ImageValue[mask, #] < 0.5 &, n]
  ]

Test:

mask = Binarize @ Import["http://i.stack.imgur.com/yoPNX.png"]

pts = pointsInMask[mask, 5000];

Graphics[{AbsolutePointSize[1], Point @ pts}]

enter image description here


Following up on my comment and borrowing a method from Vectorizing an image like "Trace Bitmap" in Inkscape:

mask = Binarize @ Import["http://i.stack.imgur.com/yoPNX.png"];

{row, col} = ImageDimensions[mask];

intf = ListInterpolation @ Reverse @ ImageData @ mask;

region = DiscretizeGraphics @ 
  RegionPlot[intf[c, r] < 1/2, {r, 1, row}, {c, 1, col},
    PlotPoints -> {row, col}, MaxRecursion -> 0]

enter image description here

You can then apply whichever of the methods from How to generate random points in a region? that you find appropriate, e.g.:

pts = randomFromRegion[region, 15000];

Graphics[{AbsolutePointSize[1], Point @ pts}]

enter image description here


In version 11, one can use ImageMesh[] in tandem with RandomPoint[], like so:

imsh = ImageMesh[ColorNegate[Import["http://i.stack.imgur.com/yoPNX.png"]]];
Graphics[Point[RandomPoint[imsh, 5000]]]

random points from binary image