Python分形盒计数-分形维度

12

我有一些图片,想要计算明科夫斯基/盒计数维度,以确定图像中的分形特征。这里有两个示例图像:

10.jpg

enter image description here

24.jpg

enter image description here

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

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函数(该函数对图像进行预处理并聚焦于具有相似特征的区域)。 - Shawn
反转阈值似乎产生了几乎相同的结果(对于我的图像,第二位小数的差异),这似乎是不正确的(应该有更大的差异)。 您是否尝试过在已知闵可夫斯基-布利甘维度的图像上运行此脚本? - Shawn
1个回答

12

拥有物理特性的分形维度可能在不同阶段收敛到不同的值。例如,一个非常细的线(但有限宽度)最初看起来是一维的,然后随着其宽度与所使用的框的大小相当,最终变成二维的。

让我们看看您生成的维度:

你看到了什么?线性拟合并不那么好。维度趋向于一个值为2。

为了诊断,让我们看看产生的灰度图像,使用您的阈值(即0.9):

enter image description here

enter image description here

自然图片几乎变成了墨水斑点。维度很快就会达到2的值,就像图表告诉我们的一样。这是因为我们几乎失去了这张图片。

现在使用50的阈值呢?

enter image description here

enter image description here

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

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

关于这个问题的一个好书籍是Michael F. Barnsley的《无处不在的分形》。


啊,我没想到要更正阈值。您建议我为每个图像单独动态设置threshold的值为mean(Z)吗?或者如果我想比较图像值,是否应该对所有图像使用相同的阈值? - Simon
1
阈值可以帮助您将图像转换为二维“画布”的紧凑子集。阈值确定像素是否在子集中。动态设置阈值与固定阈值不同。当它是动态的时,暗图像和亮图像相对于自己的光照进行比较,但是一个密集的灌木丛的图像可能不会比一棵死树或一堵墙更高维度。密集的树形图像可能会出现几乎二维的情况,就像一个巨大的墨水斑点。 - myorbs
但是动态设置阈值意味着您可以在不考虑其照明条件的情况下突出图像中的结构。因此,如果您有一组图像,无法保证相同的光照水平,那么动态设置阈值是否更可取,以便您知道所有图像都被平等处理(即为每个图像创建一个像素子集,这些像素不依赖于诸如照明条件之类的事物)?我想我很难想象为什么动态阈值可能是不好的。 - Simon
1
一个例子:一张黑暗灌木丛顶部和一些空旷明亮的天空的照片。如果将它们都用相同的阈值处理,并将暗像素视为分形的一部分,那么天空的维度显然比灌木丛低得多。但是,如果将图像分成两个部分并分别进行分析,则天空的维度接近2,而灌木丛的维度则要小得多。在这种情况下,最好使用相同的阈值。这取决于您的比较,动态阈值可能会产生您不想要的结构 :) - myorbs
我不明白为什么墨水斑点的分形维数会接近2,难道2不表示最大可能的复杂性吗? - ludog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接