使用两个 Numpy 数组执行数学运算 - 限制数量

Perform math opeartion with two Numpy array - limit the number

我有 2 个 Numpy 数组,我需要对它们执行一些基本的数学运算。
但由于最终 numpy 数组(名为 magnitude)的类型 (uint8),我也不能让此操作的结果大于 255。任何想法?除了遍历数组...

# Notice that the data type is "np.uint8", also arrays are 2D
magnitude = np.zeros((org_im_width,org_im_height), dtype=np.uint8)

# "numpy_arr_1" and "numpy_arr_2" both of the same size & type as "magnitude"

# In the following operation, I should limit the number to 255
magnitude = ( (np.int_(numpy_arr_1))**2 + (np.int_(numpy_arr_2))**2 )**0.5

# The following doesn't work obviously:
# magnitude = min(255,((np.int_(numpy_arr_1))**2+(np.int_(numpy_arr_2))**2)**0.5)

首先,如果在 magnitude = ... 创建后赋值,您将在操作中用 obtianed 替换初始 uint8 数组,因此 magnitude 不再是 uint8。

无论如何,如果只是示例中的错误,要执行您想要的操作,您可以 clamp/clipnormalize 结果操作的值:

您可以找到 np.clip,它将数组的值限制为 minmax 值:

>>> magnitude = np.clip(operation, 0, 255)

其中 operation 是您计算的幅度。事实上,你可能想要的是:

>>> magnitude = np.clip(np.sqrt(a**2 + b**2), 0, 255).astype(np.uint8)

其中 ab 分别是您的 np.int_(numpy_arr_1)np.int_(numpy_arr_2),为了便于阅读而重命名。

此外,在您的情况下,所有值都是正数,您可以将 np.clip 替换为 np.minimum:

>>> magnitude = np.minimum(np.sqrt(a**2 + b**2), 255).astype(np.uint8)

然而,这只是将矢量的幅度限制为 255(你想要的),但是对于更高幅度的 points,你将丢失大量信息。如果某个点的幅度为 1000,它将被限制为 255,因此在您的最终数组中 1000 = 255。幅度变化很大的两个点最终将具有相同的幅度(在这种情况下为 1000 和 255)。

为避免这种情况,您可以 normalize(重新缩放)您的震级范围至 [0, 255]。这意味着,如果在您的初始计算中,幅度数组在 [0, 1000] 范围内,请将其转换为 [0, 255],因此 1000 之前将是 255 之后,但 255 现在将是 63(简单的线性缩放)。

>>> tmp = np.sqrt(a**2 + b**2).astype(float)
>>> magnitude = (tmp / tmp.max() * 255).astype(np.uint8)

tmp / tmp.max() 会将所有值重新缩放到 [0, 1] 范围(如果数组是浮点数),然后乘以 255,数组再次重新缩放到 [0, 255]

如果您的震级下限不是 0,您可以执行从 [200, 1000][0, 255]re-scale 以更好地代表您的数据:

>>> tmp = np.sqrt(a**2 + b**2).astype(float)
>>> tmax, tmin = tmp.max(), tmp.min()
>>> magnitude = ((tmp - tmin) / (tmax - tmin) * 255).astype(np.uint8)