计算n维图像熵Python

3

我正在尝试计算更高维度的“图像”的熵。显而易见的方法:

from scipy.stats import entropy

kernel_radius=2
entropy_stack = np.zeros(Stack.shape)
for ii in range(kernel_radius,entropy_stack.shape[0]-kernel_radius):
    for jj in range(kernel_radius,entropy_stack.shape[1]-kernel_radius):
        for kk in range(kernel_radius,entropy_stack.shape[2]-kernel_radius):    
            entropy_stack[ii,jj,kk]=entropy(Stack[ii-kernel_radius:ii+kernel_radius,jj-kernel_radius:jj+kernel_radius,kk-kernel_radius:kk+kernel_radius].flatten())

工作正常,但速度非常慢。

有没有计算高维图像熵的实现技巧?更好的是,有没有带有此函数优化版本的软件包?

我知道scikit-image的entropy在2D中表现良好。同样,我知道matlab的entropyfilt比我当前的实现快几百倍。


FYI,scipy.stats 中的 entropy 函数需要概率作为输入,而不是数值。 - Paul Brodersen
1
此外,entropy 实现了符号流的熵计算,而不是序数流的熵计算。我建议您研究无箱估计器的熵或者至少将图像堆栈中的值分成少于256个不同的类/符号(假设您正在将图像保存在 uint8 数组中)。 - Paul Brodersen
1个回答

3

这是一种解决方案,但不幸的是它的速度也很慢(尽管它有更清洁的代码并正确处理边界)。它使用了scipy.ndimage中的generic_filter

import numpy as np
from scipy.ndimage import generic_filter
from scipy.stats import entropy

def _entropy(values):
    probabilities = np.bincount(values.astype(np.int)) / float(len(values))
    return entropy(probabilities)

def local_entropy(img, kernel_radius=2):
    """
    Compute the local entropy for each pixel in an image or image stack using the neighbourhood specified by the kernel.

    Arguments:
    ----------
    img           -- 2D or 3D uint8 array with dimensions MxN or TxMxN, respectively.
                     Input image.
    kernel_radius -- int
                     Neighbourhood over which to compute the local entropy.

    Returns:
    --------
    h -- 2D or 3D uint8 array with dimensions MxN or TxMxN, respectively.
         Local entropy.

    """
    return generic_filter(img.astype(np.float), _entropy, size=2*kernel_radius)

谢谢。这个版本肯定更干净。我需要看一下在“entropy()”中输入值和概率之间的区别。 - McMa

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