[英]How do I efficiently pixel vote, in a vectorized manner, in a 3D NumPy matrix to create a new 2D matrix?
我有一个形状为(n, height, width)
的 NumPy 矩阵,其中包含uint8
范围内的灰度图像。 每层(总共 n 个)都包含来自神经网络的预测。 我想比较所有n layers
,并为每个像素获取第二个最常见的值,并使用这个新值创建一个新的形状(height, width)
矩阵。 换句话说,我使用逐像素投票从分层矩阵中的所有矩阵创建一个新的二维矩阵。 我更喜欢第二个最常见的值,因为最常见的值是 3,出于不同的原因,我想忽略它; 这就是为什么我使用mode(vote[vote,= 3], axis=None)[0][0]
搜索第二个最常见的值的原因。 以下是一个有效的解决方案。 但是,它不是很快,因为我必须慢慢迭代。 我想使用矢量化解决方案来节省时间。
import numpy
from scipy.stats import mode
n = 84
height = 1872
width = 3128
layered_image = numpy.ndarray(shape=(n, height , width), dtype=numpy.uint8)
image = numpy.ndarray(shape=(height , width), dtype=numpy.uint8)
for i in range(0, height):
for j in range(0, width):
vote = []
for k in range(len(layered_image)):
vote.append(layered_image[k][i][j])
vote = numpy.asarray(vote, dtype=numpy.uint8)
image[i][j] = mode(vote[vote != 3], axis=None)[0][0]
感谢您的任何建议。
一种方法是外部广播平等 -
np.equal.outer(layered_image,np.arange(3)).sum(0).argmax(-1)
另一个带有掩膜处理的-
# a is the input layered_image
c0,c1,c2 = (a==0).sum(0), (a==1).sum(0), (a==2).sum(0)
out = np.where(np.maximum(c0,c1)>c2, np.where(c0>c1,0,1), 2)
另一个带有2D bincount
-
# https://stackoverflow.com/a/46256361/ @Divakar
def bincount2D_vectorized(a):
N = a.max()+1
a_offs = a + np.arange(a.shape[0])[:,None]*N
return np.bincount(a_offs.ravel(), minlength=a.shape[0]*N).reshape(-1,N)
# a is the input layered_image
b = bincount2D_vectorized(a.reshape(a.shape[0],-1).T)
out = b[:,:-1].argmax(1).reshape(a.shape[1:])
感谢Divakar , bincounting
方法非常适合我的目的。 为了防止在处理大量层时过度使用 RAM,我在此方法中添加了切片。 这有点慢,但它允许在 memory 较少的机器上进行处理; 假设slice_coordinates
是一个列表,其中包含(y, x)
元组中所有图像块的左上角坐标, prediction_overlay
3D 分层图像和prediction_mask
新的 2D 图像,切片工作如下:
for i in range(len(slice_coordinates)):
to_process = prediction_overlay [:, slice_coordinates[i][0] : slice_coordinates[i][0] + tile_height, slice_coordinates[i][1] : slice_coordinates[i][1] + tile_width]
b = bincount2D_vectorized(to_process.reshape(to_process.shape[0],-1).T)
processed = b[:,:-1].argmax(1).reshape(to_process.shape[1:])
prediction_mask [slice_coordinates[i][0] : slice_coordinates[i][0] + tile_height, slice_coordinates[i][1] : slice_coordinates[i][1] + tile_width] = processed
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.