繁体   English   中英

如何以矢量化方式在 3D NumPy 矩阵中有效地进行像素投票以创建新的二维矩阵?

[英]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:])

感谢Divakarbincounting方法非常适合我的目的。 为了防止在处理大量层时过度使用 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM