Python分形盒计数 - 分形维数

Posted

技术标签:

【中文标题】Python分形盒计数 - 分形维数【英文标题】:Python fractal box count - fractal dimension 【发布时间】:2017-12-01 06:30:35 【问题描述】:

我有一些图像要计算 Minkowski/box count dimension 以确定图像中的分形特征。以下是 2 张示例图片:

10.jpg:

24.jpg:

我正在使用以下代码来计算分形维数:

import numpy as np
import scipy

def rgb2gray(rgb):
    r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
    return gray

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 = rgb2gray(scipy.misc.imread("24.jpg"))
print("Minkowski–Bouligand dimension (computed): ", fractal_dimension(I))

从我读过的文献中,有人建议自然场景(例如24.jpg)在本质上更分形,因此应该具有更大的分形维值

它给我的结果与文献所暗示的相反:

10.jpg: 1.259

24.jpg: 1.073

我希望自然图像的分形维度大于城市图像的分形维度

我是否在代码中错误地计算了值?还是我只是错误地解释了结果?

【问题讨论】:

这项技术对我来说效果很好,我用另一个函数替换了 rgb2gray 函数(它预处理图像并专注于具有相似特征的区域) 反转阈值似乎产生几乎相同的结果(对于我的图像,差异在小数点后第二位;这似乎不正确(应该是更大的差异)。您是否尝试过使用已知图像的脚本Minkowski–Bouligand 维数? 【参考方案1】:

对于物理的分形维数,维数可能会在不同阶段收敛到不同的值。例如,一条非常细的线(但宽度有限)最初看起来是一维的,然后最终是二维的,因为它的宽度变得与使用的盒子大小相当。

让我们看看您制作的尺寸:

你看到了什么?那么线性拟合不是那么好。并且尺寸将趋向于二。 为了诊断,让我们看一下生成的灰度图像,以及您拥有的阈值(即 0.9):

大自然的画面几乎变成了墨点。正如图表告诉我们的那样,尺寸很快就会变为 2。那是因为我们几乎失去了形象。 现在阈值为 50?

有了更好的新线性拟合,城市和自然的维度分别为 1.6 和 1.8。请记住,城市图片实际上有很多结构,特别是在纹理墙壁上。

在未来,好的阈值将更接近灰度图像的平均值,这样您的图像就不会变成一团墨水!

Michael F. Barnsley 的“Fractals Everywhere”是一本很好的教科书。

【讨论】:

啊,我没想到要更正阈值。您是否建议我为每个图像分别动态设置 thresholdmean(Z) 的值?或者,如果我想将图像值相互比较,是否应该对所有图像使用相同的阈值? 阈值可帮助您将图像转换为二维“画布”的紧凑子集。阈值确定像素何时在子集中或不在子集中。动态设置阈值与固定阈值不同。当它是动态的时,较暗的图像和较亮的图像相对于它们自己的照明进行比较,但是茂密的灌木丛的图像可能与死树或墙壁相比没有更高的维度。密集的树图像可能几乎是二维的,就像一个巨大的墨迹。 但是动态设置阈值意味着无论光照条件如何,您都可以突出图像中的结构。因此,如果您有一组无法保证相同光照水平的图像,是否最好动态设置阈值,以便您知道所有图像都被平等对待(即为每个图像创建像素子集,而不是取决于诸如照明条件之类的东西)?我想我很难想象为什么动态阈值可能是一件坏事 一个例子:黑暗灌木顶部和空旷明亮的天空的照片。如果两者都用相同的阈值处理并且我们认为暗像素属于分形,那么天空显然具有比灌木低得多的维度。但是,如果您将图像一分为二,分别分析它们,您将得到天空的维度接近 2,而灌木的维度则小得多。在这种情况下,使用相同的阈值可能会更好。这仅取决于您的比较,动态阈值可能会发明您不想要的结构:)

以上是关于Python分形盒计数 - 分形维数的主要内容,如果未能解决你的问题,请参考以下文章

11E:分形盒

分形在编程中的实际应用

Python 分形算法__代码里开出来的艺术之花

分形之美

python使用递归实现一个分形图形

开源分形图 [关闭]