如何在不使用for循环的情况下将函数应用于三通道图像numpy数组的每个通道?

qxsslcnc  于 2023-05-29  发布在  其他
关注(0)|答案(1)|浏览(163)

假设我有一个三个通道的图像,其对应的numpy数组的形状为(H,W,3)。现在我创建了一个函数,它对2D numpy数组做了一些事情。我如何在不使用for循环的情况下将函数应用于图像的每个通道,因为它很慢?
我正在寻找一个类似于在Pandas中应用的功能。我尝试了np.apply_over_axes和np.apply_沿着_axis,但两个结果都不正确。
在下面的代码中,我希望分别为图像的每个通道添加高斯噪声。

test_img = np.array(train_data[0][0])
test_img.shape
# (198, 180, 3)

def add_gaussian_noise(img_, amplitude=1.0, mean=0.0, variance=1.0):
    img_ = img_.astype('float32')
    # print(img_.shape)

    # assertion failed
    # assert img_.shape == (test_img.shape[0], test_img.shape[1])
    img_ = img_ + amplitude * np.random.normal(mean, variance, img_.shape)
    img_ = np.clip(img_, 0.0, 255.0)
    return img_

test_img = np.apply_along_axis(arr= test_img, func1d= add_gaussian_noise, axis = 2)

print(test_img)

我预期的是img_.shape == (test_img.shape[0], test_img.shape[1]),但结果是我的代码中的img_.shape == (3,)
在这种情况下,优化不会产生很大的差异,但我正在寻找一个更通用的解决方案,以便在其他情况下,例如。我必须将相同的函数应用于数百张灰度图片,代码比for循环更有效。

fsi0uk1n

fsi0uk1n1#

你要找的是broadcasting。这允许您在数组的多个切片上运行操作。如果没有更多的信息,就不可能说这是否适用于您的特定情况,但这是使用Numpy做这类事情的正常方式。
许多Numpy函数都支持广播(您将在文档中看到对此的引用)。这通常是在早期的矩阵轴上完成的,因此您可能需要将通道轴转置到矩阵的开始。
编辑:正如在注解中提到的,对于少量的重复,在Python中循环是一种非常合理的方法。但我猜你是在找更普通的案子。

相关问题