Numpy计算度量的更高效代码

2024-10-02 02:38:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试实现这个指标 enter image description here

我已经设法用numpy操作来计算NUBN,所以速度很快,但是我找不到一种方法来逃避python计算DRD部分的缓慢循环。以下是我目前对DRD的计算:

def drd(im, im_gt):
    height, width = im.shape
    W = np.array([[1/math.sqrt(x**2+y**2) if x != 0 or y != 0 else 0 for x in range(-2, 3)] for y in range(-2, 3)])
    W /= W.sum()
    drd = 0
    s = []
    for y, x in zip(*np.where(im_gt != im)):
        if x > 1 and y > 1 and x + 2 < width and y + 2 < height:
            s.append(im_gt[y-2:y+3, x-2:x+3] == im_gt[y, x])
        else:
            for yy in range(y-2, y+3):
                for xx in range(x-2, x+3):
                    if xx > 1 and yy > 1 and xx < width - 1 and yy < height - 1:
                        drd += abs(im_gt[yy, xx] - im[y, x]) * W[yy-y+2, xx-x+2]
    return drd + np.sum(s * W)

drd(np.random.choice([0, 1], size=(100, 100)), np.random.choice([0, 1], size=(100, 100)))

有人能想出一个更快的方法吗?1000x1000上的计时:

enter image description here


Tags: and方法ingtforifnprange
1条回答
网友
1楼 · 发布于 2024-10-02 02:38:23

使用numpy加快速度的第一步是将操作序列分解为可应用于整个阵列的内容。让我们从一个简单的问题开始:删除W计算中的理解:

W = np.hypot(np.arange(-2, 3), np.arange(-2, 3)[:, None])
np.reciprocal(W, where=W.astype(bool), out=W)
W /= W.sum()

下一件事(上面用where=W.astype(bool)暗示)是在适当的地方使用掩蔽将条件应用于整个数组。您的算法如下所示:

For each location that does not match between im and im_gt, compute the sum of the elements of W centered on that location where they do not match.

你可以用W的卷积来计算。只需丢弃im == im_gt的位置。需要通过从W.sum()中减去来翻转im_gt == 1的位置,因为需要对零求和,而不是对这些元素求和。卷积在^{}中实现。通过使用mode='same'并仔细调整边缘像素,可以获得相同的边缘效果。您可以通过使用一个数组进行卷积来欺骗和获取边和:

from scipy.signal import convolve2d

# Compute this once outside the function
W = np.hypot(np.arange(-2, 3), np.arange(-2, 3)[:, None])
np.reciprocal(W, where=W.astype(bool), out=W)
W /= W.sum()

def drd(im, im_gt):
    m0 = im != im_gt
    m1 = im_gt == 0
    m2 = im_gt == 1
    s1 = convolve2d(m1, W, mode='same')[m0 & m1].sum()
    s2 = convolve2d(m2, W, mode='same')[m0 & m2].sum()
    return s1 + s2

相关问题 更多 >

    热门问题