首页 文章

在Python NumPy中扩展图像的最有效方法

提问于
浏览
1

我想要一个函数将图像作为numpy数组接收,并根据输入范围中指定的最大值和最小值将值重新映射到新范围(0,1) . 我有一个工作函数,但我正在迭代数组,大约需要10秒才能完成 . 有没有更有效的方法来执行此任务?也许有些内置的numpy功能我不知道?

这就是我所拥有的:

import numpy as np

def stretch(image, minimum, maximum):
    dY = image.shape[0]
    dX = image.shape[1]
    r = maximum - minimum
    image = image.flatten()
    for i in range(image.size):
        if image[i] > maximum or image[i] < minimum:
            image[i] = 1. or 0.
        else:
            image[i] = (image[i] - minimum) / r
    return image.reshape(dY, dX)

我也尝试过使用numpy.nditer而不是手动迭代for循环的上述版本,但这似乎是慢四倍(~40秒) .

有一种更有效的方法可以做到这一点,我忽视了吗?我正在使用的图像大约是16 MP . (3520,4656)

1 回答

  • 2

    Bug#1

    您的代码中存在错误 .

    image[i] = 1. or 0. 始终求值为 1.0 ,因为 1.truthy .

    相反,该块应如下所示:

    if image[i] < minimum:
        image[i] = 0.
    elif image[i] > maximum:
        image[i] = 1
    else:
        image[i] = (image[i] - minimum) / r
    

    Bug#2

    如果您的原始数组是 dtype=int 并且您将值放入其中,则它们将被强制转换为 int . 这意味着任何 float 将被向下舍入 .

    a = np.array([1])
    a[0] = 0.5
    a
    

    回报

    array([0])
    

    这可以使用下面的矢量化解决方案来解决 .

    解决方案

    通常在处理NumPy数组时尽量不要使用循环 . 使用矢量化函数可以更快,更可读 .

    def stretch(image, minimum, maximum):
        image = (image - minimum) / (maximum - minimum)
        image[image < 0] = 0
        image[image > 1] = 1
        return image
    

    一个例子(更新为 int ,对于 image 更为现实,因为@MrT指出):

    a = np.arange(1, 4).reshape(2, 2)
    stretch(a, 1, 3)
    

    回报

    array([[0. , 0.5],
           [1. , 1. ]])
    

相关问题