[PYTHON] I tried fractal dimension analysis by the box count method in 3D

Introduction

Let's quantitatively evaluate the ** beauty ** of the structure. I am doing research. As a quantification method, ** fractal dimension ** is used as one index.

And, in order to find the fractal dimension, we use a method called ** box counting method **. I did not find an example of dealing with this in 3D, so I wrote an article.

What is fractal dimension?

[Fractal dimension](https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%AB%E6% AC% A1% E5% 85% 83) Wikipedia has it like this. To put it simply, the dimensions between 1D and 2D, and between 2D and 3D can be represented by ** non-integer values **. You can express ** complexity **. Quantitative evaluation of landscapes and paintings is performed using this.

Fractal dimension analysis

This time, as an example, we will use a * 200 × 200 × 200 * cube. Let's experiment as a 3D * numpy * array initialized with * 1 *.

Actually read * STL * file numpy-stlArrange using. (Details will be written in the future)

Box counting method

Regarding the box counting method, I think this article is easy to understand, so I will link to it. Fractal analysis of surface roughness curve

Think of this three-dimensionally.

  1. Divide the cube into a grid
  2. Count if there are objects in the grid
  3. Let grid_size be the length of the grid side and n be the count.
  4. Plot log (grid_size) and log (n)
  5. Perform linear regression by least squares method
  6. Let the regression coefficient be the fractal dimension

We will change the size of this grid one by one.

A function that counts the elements contained in a box

Scan the 3D array in the order of x direction → y direction → z direction

3d_fractal.py


def count(arr, x, y, z, b):
    i = j = k = 0
    b_tmp  = b
    b_tmp2 = b
    ct = 0

    j_tmp = b
    k_tmp = b
    while k < z:
        while j < y:
            while i < x:
                if (np.any(arr[i:b, j:j_tmp, k:k_tmp] == 1)):
                    ct += 1
                i += b_tmp
                b += b_tmp
            #Wrap back
            j += b_tmp2
            j_tmp += b_tmp2
            b = b_tmp2
            i = 0
        #Wrap back
        k += b_tmp2
        k_tmp += b_tmp2
        b = b_tmp2
        j = b_tmp2

        i = 0
        j = 0

main function

Repeat the process of count () until the grid size changes from * 200 * to * 1/2 * by 100, 50, ... and * 1 *. When the grid size is * 1 *, the count should be * 200 x 200 x 200 = 80,00,000 *.

3d_fractal.py


def main():

    x = y = z = 200

    graph_x = []
    graph_y = []

    array3d = np.ones((x, y, z))
    ct_1 = np.count_nonzero(array3d == 1)

    grid_size = max(x, y, z)

    while grid_size >= 1:
        n = count(array3d, x, y, z, grid_size)
        graph_x.append(math.log(grid_size))
        graph_y.append(math.log(n))
        print(grid_size, n)
        print (math.log(grid_size), math.log(n))
        grid_size = int(grid_size / 2)

Linear regression

Perform linear regression from the counted result. Scikit-learn class for regression processing Use sklearn.linear_model.LinearRegression.

3d_fractal.py


    graph_x = np.array(graph_x).reshape((len(graph_x), 1)) #Make one row
    graph_y = np.array(graph_y).reshape((len(graph_y), 1))

    model_lr = LinearRegression()

    #Predictive model creation
    model_lr.fit(graph_x, graph_y)

    plt.xlabel("log(grid_size)")
    plt.ylabel("log(n)")

    plt.plot(graph_x, graph_y, 'o')
    plt.plot(graph_x, model_lr.predict(graph_x), linestyle="solid")

    plt.grid()
    plt.show()

    #Fractal dimension=Regression coefficient
    fractal = model_lr.coef_[0][0] * -1 

    print("Fractal : ", fractal)

result

Figure_1.png Here is the logarithmic graph of the result. Grid size * log * on the horizontal axis

200 1
5.298317366548036 0.0
100 8
4.605170185988092 2.0794415416798357
50 64
3.912023005428146 4.1588830833596715
25 512
3.2188758248682006 6.238324625039508
12 4913
2.4849066497880004 8.499640032168648
6 39304
1.791759469228055 10.579081573848484
3 300763
1.0986122886681098 12.614077858172898
1 8000000
0.0 15.89495209964411
Fractal :  3.004579190748091

The result looks like this. The fractal dimension is * 3.004579190748091 * So it's almost a theoretical value. When repeating from * 200 *, there was a case where it was not divisible by * 25/2 = 12 *, so there was a slight deviation.

Summary

--We were able to verify the three-dimensional fractal dimension analysis by the box count method. -Next time, I would like to write a method to calculate the fractal dimension directly from the * STL * file.

References

"Fractal analysis of surface roughness curve", Takeo Kono, (2010), Nagano Prefectural Institute of Technology Research Bulletin, No.5, p.P52-P55.

Recommended Posts

I tried fractal dimension analysis by the box count method in 3D
I tried the least squares method in Python
I tried cluster analysis of the weather map
I tried simulating the "birthday paradox" in Python
Before the coronavirus, I first tried SARS analysis
I tried FX technical analysis by AI "scikit-learn"
I tried using the Datetime module by Python
I tried to predict the change in snowfall for 2 years by machine learning
[New Corona] Is the next peak in December? I tried trend analysis with Python!
Draw a graph in Julia ... I tried a little analysis
I tried to graph the packages installed in Python
I tried to predict the J-League match (data analysis)
I tried clustering ECG data using the K-Shape method
I tried to simulate the dollar cost averaging method
I tried increasing or decreasing the number by programming
I tried the simplest method of multi-label document classification
What I learned by participating in the ISUCON10 qualifying
I made a class to get the analysis result by MeCab in ndarray with python
I tried the super-resolution algorithm "PULSE" in a Windows environment
I tried morphological analysis of the general review of Kusoge of the Year
I tried to summarize the code often used in Pandas
I tried "How to get a method decorated in Python"
I tried to illustrate the time and time in C language
I tried programming the chi-square test in Python and Java.
I tried to summarize the commands often used in business
I tried to implement the mail sending function in Python
I tried to summarize the contents of each package saved by Python pip in one line
[RHEL7 / CentOS7] I put in the log monitoring tool swatch and tried to notify by email
I tried the changefinder library!
I tried to describe the traffic in real time with WebSocket
Movement that changes direction in the coordinate system I tried Python 3
I got an AttributeError when mocking the open method in python
Feature extraction by TF method using the result of morphological analysis
Perform morphological analysis in the machine learning environment launched by GCE
I tried to visualize the Beverage Preference Dataset by tensor decomposition.
I tried to process the image in "sketch style" with OpenCV
The first time a programming beginner tried simple data analysis by programming
I tried to summarize the commands used by beginner engineers today
I tried to make an analysis base of 5 patterns in 3 years
I tried to predict by letting RNN learn the sine wave
I tried to process the image in "pencil style" with OpenCV
I tried to solve the shift scheduling problem by various methods
I tried to summarize the frequently used implementation method of pytest-mock
I tried to display the analysis result of the natural language processing library GiNZA in an easy-to-understand manner
I tried to summarize all the Python plots used in the research by active science graduate students [Basic]
I tried to open the latest data of the Excel file managed by date in the folder with Python