有没有办法使用 numpy 数组函数来获得同样的效果?
Is there a way to use numpy array functions to get this same effect?
我正在尝试使用以下代码过滤掉给定公差范围内的所有非灰度值。它给出了预期的结果,但运行速度太慢而无法在实践中使用。有没有办法使用 numpy 操作来执行以下操作?
for i in range(height):
for j in range(width):
r, g, b = im_arr[i][j]
r = (r + 150) / 2
g = (g + 150) / 2
b = (b + 150) / 2
mean = (r + g + b) / 3
diffr = abs(mean - r)
diffg = abs(mean - g)
diffb = abs(mean - b)
maxdev = 2
if (diffr + diffg + diffb) > maxdev:
im_arr[i][j][0] = 0
im_arr[i][j][1] = 0
im_arr[i][j][2] = 0
这可以在没有任何循环的情况下完成。我会尽量把每一步都打成专线
import numpy as np
im_arr = np.random.rand(300,400,3) # Assuming this how you image looks like
img_shifted = (im_arr + 15) / 2 # This can be done in one go
mean_v = np.mean(img_shifted, axis=2) # Compute the mean along the channel axis
diff_img = np.abs(mean_v[:,:,None] - img_shifted) # Broadcasting to subtract n x m from n x m x k
maxdev = 2
selection = np.sum(diff_img, axis=2) > maxdev
im_arr[selection] = 0 # Using fancy indexing with booleans
普通循环 Python 很慢:numpy
的优点之一是
遍历数组是高度优化的。不评论算法,只用numpy
就可以得到相同的结果,这样会快很多
由于im_arr
是一张图片,所以dtype
很可能是np.uint8
。
那只有 8 位,所以你必须小心溢出。在您的代码中,当您将 150 添加到一个数字时,结果将是 np.int64
类型。但是,如果将 150 加到 8 位 np.ndarray
,结果仍然是 np.uint8
类型并且它可能会溢出。
您可以更改数组类型(使用 astype
)或添加浮点数,这会自动将数组提升为 float
mod_img = (im_arr + 150.)/2 # the point of "150." is important
signed_dif = mod_img - np.mean(mod_img, axis=2, keepdims=True)
collapsed_dif = np.sum(np.abs(signed_dif), axis=2)
maxdev = 2
im_arr[collapsed_dif > maxdev] = 0
我正在尝试使用以下代码过滤掉给定公差范围内的所有非灰度值。它给出了预期的结果,但运行速度太慢而无法在实践中使用。有没有办法使用 numpy 操作来执行以下操作?
for i in range(height):
for j in range(width):
r, g, b = im_arr[i][j]
r = (r + 150) / 2
g = (g + 150) / 2
b = (b + 150) / 2
mean = (r + g + b) / 3
diffr = abs(mean - r)
diffg = abs(mean - g)
diffb = abs(mean - b)
maxdev = 2
if (diffr + diffg + diffb) > maxdev:
im_arr[i][j][0] = 0
im_arr[i][j][1] = 0
im_arr[i][j][2] = 0
这可以在没有任何循环的情况下完成。我会尽量把每一步都打成专线
import numpy as np
im_arr = np.random.rand(300,400,3) # Assuming this how you image looks like
img_shifted = (im_arr + 15) / 2 # This can be done in one go
mean_v = np.mean(img_shifted, axis=2) # Compute the mean along the channel axis
diff_img = np.abs(mean_v[:,:,None] - img_shifted) # Broadcasting to subtract n x m from n x m x k
maxdev = 2
selection = np.sum(diff_img, axis=2) > maxdev
im_arr[selection] = 0 # Using fancy indexing with booleans
普通循环 Python 很慢:numpy
的优点之一是
遍历数组是高度优化的。不评论算法,只用numpy
就可以得到相同的结果,这样会快很多
由于im_arr
是一张图片,所以dtype
很可能是np.uint8
。
那只有 8 位,所以你必须小心溢出。在您的代码中,当您将 150 添加到一个数字时,结果将是 np.int64
类型。但是,如果将 150 加到 8 位 np.ndarray
,结果仍然是 np.uint8
类型并且它可能会溢出。
您可以更改数组类型(使用 astype
)或添加浮点数,这会自动将数组提升为 float
mod_img = (im_arr + 150.)/2 # the point of "150." is important
signed_dif = mod_img - np.mean(mod_img, axis=2, keepdims=True)
collapsed_dif = np.sum(np.abs(signed_dif), axis=2)
maxdev = 2
im_arr[collapsed_dif > maxdev] = 0