Distributions#

Distributions are used in the Dead Leaves Model to sample object parameters such as size, aspect ratio, orientation, color, and texture. They are specified as dictionaries with the distribution type as key and its parameters as values.

Constant#

The Constant distribution returns a fixed deterministic value every time it is sampled. Use this when you want a parameter to remain unchanged.

Use case: Fixed parameter for all leaves.

{
    "constant": {
        "value": <value>
    }
}

Example: Constant size

Hide code cell source

from deadleaves import LeafGeometryGenerator, LeafAppearanceSampler, ImageRenderer

model = LeafGeometryGenerator(
    "circular", 
    {"area": {"constant": {"value": 5000.0}}},
    (256,256)
)
leaf_table, segmentation_map = model.generate_segmentation()

colormodel = LeafAppearanceSampler(leaf_table)
colormodel.sample_color({"gray": {"uniform": {"low": 0.0, "high": 1.0}}})

renderer = ImageRenderer(colormodel.leaf_table, segmentation_map)
renderer.render_image()
renderer.show(figsize = (3,3))
../_images/d89ff82d616cb48765c7823fa28cf90efadfb323ad833ca90b883a34aacd51dc.png

Uniform (from PyTorch)#

The Uniform distribution samples values evenly from a range [low, high] (where \(a=\)low and \(b=\)high).

\[\begin{split} f(x) = \begin{cases} \frac{1}{b-a}, & \text{for } x\in[a,b] \\ 0, &\text{else}.\end{cases} \end{split}\]

Use case: Random but equally likely values, e.g. random orientation or hue.

{
    "uniform": {
        "low": <value>, 
        "high": <value>
    }
}

Example: Uniform size and luminance

Hide code cell source

from deadleaves import LeafGeometryGenerator, LeafAppearanceSampler, ImageRenderer

model = LeafGeometryGenerator(
    "circular", 
    {"area": {"uniform": {"low": 100.0, "high": 10000.0}}},
    (256,256)
)
leaf_table, segmentation_map = model.generate_segmentation()

colormodel = LeafAppearanceSampler(leaf_table)
colormodel.sample_color({"gray": {"uniform": {"low": 0.0, "high": 1.0}}})

renderer = ImageRenderer(colormodel.leaf_table, segmentation_map)
renderer.render_image()
renderer.show(figsize = (3,3))
../_images/d18e1cea0076fa84a42253f6d3964f9f96b70dbcc1f45c19c662ea893d89403b.png

Normal (from PyTorch)#

The Normal distribution samples values from a Gaussian (bell-shaped) distribution with mean \(\mu=\)loc and standard deviation \(\sigma=\)scale.

\[ f(x) = \frac{1}{\sigma\sqrt{2\pi}}\exp\left(-\frac{1}{2}\left(\frac{x-\mu}{\sigma}\right)^2\right) \]
../_images/3658f8480bcb09f909167fc9550c6d12bdd7c7406591ab983b0e4214df1a4019.png

Use case: Gaussian noise or color.

{
    "normal": {
        "loc": <value>, 
        "scale": <value>
    }
}

Example: Normal size and luminance

Hide code cell source

from deadleaves import LeafGeometryGenerator, LeafAppearanceSampler, ImageRenderer

model = LeafGeometryGenerator(
    "circular", 
    {"area": {"normal": {"loc": 10000.0, "scale": 2000.0}}},
    (256,256)
)
leaf_table, segmentation_map = model.generate_segmentation()

colormodel = LeafAppearanceSampler(leaf_table)
colormodel.sample_color({"gray": {"normal": {"loc": 0.5, "scale": 0.25}}})

renderer = ImageRenderer(colormodel.leaf_table, segmentation_map)
renderer.render_image()
renderer.show(figsize = (3,3))
../_images/564490e9a94e31750c4a911e43cbfdd78fc6d9b20d419dc7c1b44eaccab70d4e.png

Beta (from PyTorch)#

The Beta distribution samples values in the range [0,1] and is controlled by two concentration parameters \(\alpha=\)concentration0 and \(\beta=\)concentration1.

\[\begin{split} f(x) = \begin{cases} \frac{x^{\alpha-1}(1-x)^{\beta-1}}{B(\alpha,\beta)}, &\text{for } x\in[0,1] \\ 0, &\text{else.} \end{cases} \end{split}\]
../_images/4c73e6a23f01da06e148be8856aa78aa475b1ab6f64bbc2d365337ac26f45976.png

Use case: Random proportions or normalized parameters, e.g. aspect ratio or blending factors.

{
    "beta": {
        "concentration0": <value>, 
        "concentration1": <value>
    }
}

Example: Beta aspect ratio

Hide code cell source

from deadleaves import LeafGeometryGenerator, LeafAppearanceSampler, ImageRenderer
import torch

model = LeafGeometryGenerator(
    "ellipsoid", 
    {
        "area": {"constant": {"value": 5000.0}},
        "orientation": {"uniform": {"low": 0.0, "high": 2*torch.pi}},
        "aspect_ratio": {"beta": {"concentration0": 5, "concentration1": 13}}
        },
    (256,256)
)
leaf_table, segmentation_map = model.generate_segmentation()

colormodel = LeafAppearanceSampler(leaf_table)
colormodel.sample_color({"gray": {"uniform": {"low": 0.0, "high": 1.0}}})

renderer = ImageRenderer(colormodel.leaf_table,segmentation_map)
renderer.render_image()
renderer.show(figsize = (3,3))
../_images/3d7307e2363bdad8f0be1f8e15c19756f4e3529898fa2189c21d3034db182e97.png

Poisson (from PyTorch)#

The Poisson distribution generates integer counts based on a given rate \(\lambda\).

\[ P(k) = e^{-\lambda}\frac{\lambda^k}{k!} \]
../_images/d5b1e26b046291cb495a004824d28a36d387d376031af527a74e781602fb1e2f.png

Use case: Polygons with random number of vertices.

{
    "poisson": {
        "rate": <value>
    }
}

Example: Polygons with Poisson vertices number

Hide code cell source

from deadleaves import LeafGeometryGenerator, LeafAppearanceSampler, ImageRenderer

model = LeafGeometryGenerator(
    "polygon", 
    {
        "area": {"powerlaw": {"low": 100.0, "high": 10000.0, "k": 1.5}},
        "n_vertices": {"poisson": {"rate": 5}},
        },
    (256,256)
)
leaf_table, segmentation_map = model.generate_segmentation()

colormodel = LeafAppearanceSampler(leaf_table)
colormodel.sample_color({"gray": {"uniform": {"low": 0.0, "high": 1.0}}})

renderer = ImageRenderer(colormodel.leaf_table, segmentation_map)
renderer.render_image()
renderer.show(figsize = (3,3))
../_images/78fe83fd5f19f39e3cc6c73418e6110cf1b4dc5f47856df54a769efa915807bf.png

Powerlaw#

The PowerLaw distribution is useful for heavy-tailed sizes, common in natural phenomena. It is parameterized via a lower (low, \(x_\min\)) and an upper bound (high, \(x_\max\)) and the exponent \(k\).

\[\begin{split} f(x) = \begin{cases} \frac{k-1}{x_{\min}^{1-k}-x_{\max}^{1-k}}\cdot x^{-k}, & \text{for } x\in[x_{\min}, x_{\max}] \\ 0, & \text{else.} \end{cases} \end{split}\]

For continuity with respect to \(k\) the distribution for \(k=1\) is given by

\[\begin{split} f(x) = \begin{cases} \frac{1}{\ln(x_{\max})-\ln(x_{\min})}\cdot x^{-1}, & \text{for } x\in[x_{\min}, x_{\max}] \\ 0, & \text{else.} \end{cases} \end{split}\]

For \(k=0\) the distribution equals a uniform distribution between the lower and the upper bound.

../_images/c51c407df88ad2b18b0d15fde206333ea238b133c7f52b352b3d3ca7189c3425.png

Use case: Generating leaf sizes with many small and few large objects.

{
    "powerlaw": {
        "low": <value>, 
        "high": <value>, 
        "k": <value>
    }
}

Example: Powerlaw size and saturation

Hide code cell source

from deadleaves import LeafGeometryGenerator, LeafAppearanceSampler, ImageRenderer

model = LeafGeometryGenerator(
    "circular", 
    {
        "area": {"powerlaw": {"low": 100.0, "high": 10000.0, "k": 1.5}}
        },
    (256,256)
)
leaf_table, segmentation_map = model.generate_segmentation()

colormodel = LeafAppearanceSampler(leaf_table)
colormodel.sample_color(
    {
        "H": {"normal": {"loc": 0.6, "scale": 0.1}},
        "S": {"powerlaw": {"low": 0.2, "high": 1.0, "k": 3}},
        "V": {"normal": {"loc": 0.6, "scale": 0.1}}
        }
)

renderer = ImageRenderer(colormodel.leaf_table, segmentation_map)
renderer.render_image()
renderer.show(figsize = (3,3))
../_images/42382a73955f4f02f6bd828b58b86629b7e1061ec2b0b5e110740258817a0ad0.png

Cosine#

The Cosine distribution produces periodic variations for values between \(-\pi\) and \(\pi\):

\[\begin{split} f(x) = \begin{cases} \frac{1}{2\pi} \left(1+A\cdot\cos(F\cdot x)\right), & \text{for } x\in[-\pi,\pi] \\ 0, & \text{else.} \end{cases} \end{split}\]

The frequency, \(F\) has to be an integer and specifies the number of phases on the value range. The amplitude, \(A\) changes the intensity between 0.0 and 1.0.

../_images/482f2f6ae1fb2e28ca890b8b5776768a2b10f3abdebbc778ca4b4d0bf60abe1f.png

Use case: Orientations of phase-like variations with periodic structure.

{
    "cosine": {
        "amplitude": <value>, 
        "frequency": <value>
    }
}

Note

Random variables with this distribution always produce values between \(-\pi\) and \(\pi\) and are mainly useful to parameterized orientation distributions.

Example: Cosine orientation

Hide code cell source

from deadleaves import LeafGeometryGenerator, LeafAppearanceSampler, ImageRenderer

model = LeafGeometryGenerator(
    "ellipsoid", 
    {
        "area": {"constant": {"value": 1000.0}},
        "orientation": {"cosine": {"amplitude": 0.5, "frequency": 4}},
        "aspect_ratio": {"constant": {"value": 0.5}}
        },
    (256,256)
)
leaf_table, segmentation_map = model.generate_segmentation()

colormodel = LeafAppearanceSampler(leaf_table)
colormodel.sample_color({"gray": {"uniform": {"low": 0.0, "high": 1.0}}})

renderer = ImageRenderer(colormodel.leaf_table, segmentation_map)
renderer.render_image()
renderer.show(figsize = (3,3))
../_images/a05a083e7de38348b6689180e816865efe85b62bab8de3ff6946817e0b7e0f1b.png

Expcosine#

The ExpCosine distribution is a sharply peaked periodic distribution, useful for strongly directional parameters.

\[\begin{split} f(x) = \begin{cases} \frac{\exp\left(-c \cdot \sqrt{1 - \cos(F \cdot x)}\right)}{\int_{-\pi}^{\pi} f(x) dx}, & \text{for } x\in[-\pi,\pi] \\ 0, & \text{else.} \end{cases} \end{split}\]

The frequency, \(F\) has to be an integer and specifies the number of periodic peaks on the value range. The positive exponential_constant, \(c\) sets the strength of the peak.

../_images/95a5e25d57f050cbe0ddac0e9dedb449e8d5f83cd86c44fa6283e8d121b309d3.png

Use case: Leaf orientations with a strong preferred direction, e.g. cardinal bias.

{
    "expcosine": {
        "frequency": <value>,
        "exponential_constant": <value>
    }
}

Note

Random variables with this distribution always produce values between \(-\pi\) and \(\pi\) and are mainly useful to parameterized orientation distributions.

Example: Exponential cosine orientation

Hide code cell source

from deadleaves import LeafGeometryGenerator, LeafAppearanceSampler, ImageRenderer

model = LeafGeometryGenerator(
    "ellipsoid", 
    {
        "area": {"constant": {"value": 1000.0}},
        "orientation": {"expcosine": {"frequency": 4, "exponential_constant": 3}},
        "aspect_ratio": {"constant": {"value": 0.5}}
        },
    (256,256)
)
leaf_table, segmentation_map = model.generate_segmentation()

colormodel = LeafAppearanceSampler(leaf_table)
colormodel.sample_color({"gray": {"uniform": {"low": 0.0, "high": 1.0}}})

renderer = ImageRenderer(colormodel.leaf_table, segmentation_map)
renderer.render_image()
renderer.show(figsize = (3,3))
../_images/7166d856cfc9a6e536e67ab3aecc9bd3a78f4d822e0102fd585ec0667977d84d.png

Image#

The Image distribution samples from a set of image files in a given directory. The class will discover all image type files in dir and uniformly sample images from the list.

Use case: Assign color or texture by sampling existing images or texture patches, respectively.

{
    "image": {
        "dir": <value>
    }
}

Note

Sampling from this distribution will return one or multiple paths to image(s) in dir. In particular, it will sample from all available image files in the directory provided.

Example: Color and texture from images

Hide code cell source

from deadleaves import LeafGeometryGenerator, LeafAppearanceSampler, ImageRenderer

model = LeafGeometryGenerator(
    "circular", 
    {
        "area": {"constant": {"value": 5000.0}}
        },
    (256,256)
)
leaf_table, segmentation_map = model.generate_segmentation()

colormodel = LeafAppearanceSampler(leaf_table)
colormodel.sample_color({
        "source": {"image": {"dir": "../../examples/images"}}
    })
colormodel.sample_texture({
        "source": {"image": {"dir": "../../examples/textures/brodatz"}},
        "alpha": {"normal": {"loc": 0.0, "scale": 0.4}},
    })

renderer = ImageRenderer(colormodel.leaf_table, segmentation_map)
renderer.render_image()
renderer.show(figsize = (3,3))
../_images/dbf7f67547031c52e429ca1d9771884a59c87fcfb877def0f838c329fd900867.png