4
$\begingroup$

I want to create binary images by upsampling a series of greyscale images (192 x 144 resolution) by a factor of 10 with the new pixel values being a pseudorandom distribution of 0's & 1's based on the original grey level value. The new resolution would be 1920 x 1440.

Here is a small example of a greyscale image:

i = Image[{{0.16, 0.22, 0.32}, {0.73, 0.06, 0.13}, {0., 0.86, 0.18}}, ImageSize->100]

enter image description here

The following function gives the desired result for such small images/arrays:

SeedRandom[123]
resize[dat_] :=
 Map[SparseArray[
  Partition[
   RandomSample[
    ConstantArray[0, IntegerPart[(1 - #)*100]]~Join~
     ConstantArray[1, IntegerPart[100 #]]
  ], 10]] &, dat, {2}]

  s = resize[ImageData@i];
  bin = ArrayFlatten[s];
  Image[bin, ImageSize -> 100]

enter image description here

However, when I try to uses it for a larger image ArrayFlatten gets upset...

SeedRandom[123]
bigi = Image@RandomReal[1, {50, 50}, WorkingPrecision -> 2]

enter image description here

ArrayFlatten[resize[ImageData@bigi]]

enter image description here

Obviously, I am stepping outside of ArrayFlatten's defined parameters, but I am unable to decipher the meaning of the error message...

Why is this happening?

Is there a simpler way to achieve my desired result for larger greyscale images?

$\endgroup$
2
  • 1
    $\begingroup$ This is probably a rounding issue. After all, not all matrices in the result of resize have the same dimension. $\endgroup$ Commented Oct 11, 2020 at 8:10
  • 1
    $\begingroup$ Also, I think SparseArray should be avoided here because the resulting arrays are not at all sparse. $\endgroup$ Commented Oct 11, 2020 at 11:43

2 Answers 2

3
$\begingroup$

This method is short, but slow at higher resolutions:

ImageApply[RandomVariate@*BernoulliDistribution, ImageResize[img, {100, 100}]]

Instead, it makes more sense to pre-generate a random image first which is much faster at high resolutions:

With[{dims = {1920, 1440}}, 
 Binarize[ImageSubtract[ImageResize[img, dims], RandomImage[1, dims]],0]]

See also my answer here.

$\endgroup$
1
  • $\begingroup$ Fascinating! While the original pixel shapes are obliterated, the overall binary distributions appear to be spatially similar. $\endgroup$
    – geordie
    Commented Oct 11, 2020 at 0:08
3
$\begingroup$

Maybe using RandomChoice works better (it does so for me).

f[img_, k_] := Image[ArrayFlatten[
    Map[
     RandomChoice[{1 - #, #} -> {0, 1}, {k, k}] &,
     ImageData[img],
     {2}
     ]
    ]];

Example:

f[ExampleData[{"Texture", "Bark"}], 5]
$\endgroup$
1
  • $\begingroup$ This works, although the cell tally's have a probabilistic weight rather than an exact representation of the grey-value. I'm still curious as to why this would be easier for ArrayFlatten to handle for large images than shuffling two ConstantArray's and partitioning. Is it a packed-/unpacked-array issue? $\endgroup$
    – geordie
    Commented Oct 11, 2020 at 0:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.