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

时间:2015-01-07 10:49:10

标签: numpy

我有2个Numpy数组,我需要对它们执行一些基本的数学运算 但是由于最终numpy数组(名为uint8)的类型(magnitude),我也不能将此操作的结果大于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)

1 个答案:

答案 0 :(得分:3)

首先,如果你在创建之后分配magnitude = ...,你将用操作中的obtia替换初始的uint8数组,所以幅度不再是uint8了。

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

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

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

操作是您计算的幅度。事实上,你可能想要的是:

>>> 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]的{​​{3}}更好地代表您的数据:

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