Skip to content

Instantly share code, notes, and snippets.

@rougier
Last active August 13, 2024 10:35
Show Gist options
  • Save rougier/e5eafc276a4e54f516ed5559df4242c0 to your computer and use it in GitHub Desktop.
Save rougier/e5eafc276a4e54f516ed5559df4242c0 to your computer and use it in GitHub Desktop.
Fractal dimension computing
# -----------------------------------------------------------------------------
# From https://en.wikipedia.org/wiki/Minkowski–Bouligand_dimension:
#
# In fractal geometry, the Minkowski–Bouligand dimension, also known as
# Minkowski dimension or box-counting dimension, is a way of determining the
# fractal dimension of a set S in a Euclidean space Rn, or more generally in a
# metric space (X, d).
# -----------------------------------------------------------------------------
import scipy.misc
import numpy as np
def fractal_dimension(Z, threshold=0.9):
# Only for 2d image
assert(len(Z.shape) == 2)
# From https://github.com/rougier/numpy-100 (#87)
def boxcount(Z, k):
S = np.add.reduceat(
np.add.reduceat(Z, np.arange(0, Z.shape[0], k), axis=0),
np.arange(0, Z.shape[1], k), axis=1)
# We count non-empty (0) and non-full boxes (k*k)
return len(np.where((S > 0) & (S < k*k))[0])
# Transform Z into a binary array
Z = (Z < threshold)
# Minimal dimension of image
p = min(Z.shape)
# Greatest power of 2 less than or equal to p
n = 2**np.floor(np.log(p)/np.log(2))
# Extract the exponent
n = int(np.log(n)/np.log(2))
# Build successive box sizes (from 2**n down to 2**1)
sizes = 2**np.arange(n, 1, -1)
# Actual box counting with decreasing size
counts = []
for size in sizes:
counts.append(boxcount(Z, size))
# Fit the successive log(sizes) with log (counts)
coeffs = np.polyfit(np.log(sizes), np.log(counts), 1)
return -coeffs[0]
I = scipy.misc.imread("sierpinski.png")/256.0
print("Minkowski–Bouligand dimension (computed): ", fractal_dimension(I))
print("Haussdorf dimension (theoretical): ", (np.log(3)/np.log(2)))
@VaeKnt
Copy link

VaeKnt commented Aug 12, 2024

Hello, thank you very much for this function. I am finding it very useful in my study of fractals.

However, I drew a jagged line and tried to compute the fractal dimension

Using this code, I get a dimension of around 0.94 which is clearly wrong as it is < 1.

Why am I getting such a number?

Additionally, with other free fractal analysis software, I get a dimension of around 1.088

This is the line for reference
testcurve

@delton137
Copy link

FWIW the calculation is approximate.. also look at my comment above, there might still be a subtle issue with this code.

@VaeKnt
Copy link

VaeKnt commented Aug 13, 2024

Hi delton137!

I used another simple line that I generated, and then with altering the number of boxes, and then after iterating and computing the mean, I believe I got a better estimate. For this other curve, the box-count dimension was 1.06 ish. And it was well within the 95% CI range when I compared it to the FD from the one measured by the software.

I think I hopefully solved my own problem. I came across some papers re: optimal sizes of boxes. I will need to see how to implement that!

Also, I saw that you are also working in medical imaging. It is very inspiring to see interest in fractals and medical imaging. I am but a mere medical student currently, I hope to see a lot more fractals in the future, and a lot more collaboration!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment