Browse Source

Fractal dimension calculation

Yann Weber 6 years ago
commit
d25381a607
1 changed files with 55 additions and 0 deletions
  1. 55
    0
      gte/fractdim.py

+ 55
- 0
gte/fractdim.py View File

@@ -0,0 +1,55 @@
1
+import sys
2
+import numpy as np
3
+import scipy
4
+import scipy.misc
5
+
6
+def rgb2gray(rgb):
7
+    r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
8
+    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
9
+    return gray
10
+
11
+def fractal_dimension(Z, threshold=None):
12
+    ''' @return Minkowski–Bouligand dimension (computed) '''
13
+    # Only for 2d image
14
+    assert(len(Z.shape) == 2)
15
+
16
+    # From https://github.com/rougier/numpy-100 (#87)
17
+    def boxcount(Z, k):
18
+        S = np.add.reduceat(
19
+            np.add.reduceat(Z, np.arange(0, Z.shape[0], k), axis=0),
20
+                               np.arange(0, Z.shape[1], k), axis=1)
21
+
22
+        # We count non-empty (0) and non-full boxes (k*k)
23
+        return len(np.where((S > 0) & (S < k*k))[0])
24
+
25
+    if threshold is None:
26
+        threshold = np.mean(Z)
27
+        if threshold < 0.2:
28
+            threshold = 0.2
29
+
30
+    # Transform Z into a binary array
31
+    Z = (Z < threshold)
32
+
33
+    # Minimal dimension of image
34
+    p = min(Z.shape)
35
+
36
+    # Greatest power of 2 less than or equal to p
37
+    n = 2**np.floor(np.log(p)/np.log(2))
38
+
39
+    # Extract the exponent
40
+    n = int(np.log(n)/np.log(2))
41
+
42
+    # Build successive box sizes (from 2**n down to 2**1)
43
+    sizes = 2**np.arange(n, 1, -1)
44
+
45
+    # Actual box counting with decreasing size
46
+    counts = []
47
+    for size in sizes:
48
+        counts.append(boxcount(Z, size))
49
+
50
+    # Fit the successive log(sizes) with log (counts)
51
+    coeffs = np.polyfit(np.log(sizes), np.log(counts), 1)
52
+    return -coeffs[0]
53
+
54
+I = rgb2gray(scipy.misc.imread(sys.argv[1]))
55
+print("%f:%s" % (fractal_dimension(I), sys.argv[1]))

Loading…
Cancel
Save